Coder Social home page Coder Social logo

domaindrivendev / swashbuckle.webapi Goto Github PK

View Code? Open in Web Editor NEW
3.1K 171.0 679.0 3.5 MB

Seamlessly adds a swagger to WebApi projects!

License: BSD 3-Clause "New" or "Revised" License

C# 71.49% JavaScript 10.10% CSS 11.76% HTML 2.65% ASP 0.03% Pascal 3.97%

swashbuckle.webapi's Introduction

๐Ÿ“ฃ Calling for Maintainers
With the introduction of ASP.NET Core, I've now shifted my focus to the Core-specific project - Swashbuckle.AspNetCore. That will be receiving most of my (already limited) personal time, and so I won't have the capacity to maintain this one at a sufficient rate. Still, I'd love to see it live on and am seeking one or two "core" contributors / maintainers to help out. Ideally, these would be people who have already contributed through PRs and understand the inner workings and overall design. Once signed-up, we can agree on an approach that works - ultimately, I want to remove myself as the bottleneck to merging PRs and getting fresh Nugets published. If you're interested, please let me know by adding a comment here

Swashbuckle

Build status

Seamlessly adds a Swagger to WebApi projects! Combines ApiExplorer and Swagger/swagger-ui to provide a rich discovery, documentation and playground experience to your API consumers.

In addition to its Swagger generator, Swashbuckle also contains an embedded version of swagger-ui which it will automatically serve up once Swashbuckle is installed. This means you can complement your API with a slick discovery UI to assist consumers with their integration efforts. Best of all, it requires minimal coding and maintenance, allowing you to focus on building an awesome API!

And that's not all ...

Once you have a Web API that can describe itself in Swagger, you've opened the treasure chest of Swagger-based tools including a client generator that can be targeted to a wide range of popular platforms. See swagger-codegen for more details.

Swashbuckle Core Features:

  • Auto-generated Swagger 2.0
  • Seamless integration of swagger-ui
  • Reflection-based Schema generation for describing API types
  • Extensibility hooks for customizing the generated Swagger doc
  • Extensibility hooks for customizing the swagger-ui
  • Out-of-the-box support for leveraging Xml comments
  • Support for describing ApiKey, Basic Auth and OAuth2 schemes ... including UI support for the Implicit OAuth2 flow

Swashbuckle 5.0

Swashbuckle 5.0 makes the transition to Swagger 2.0. The 2.0 schema is significantly different to its predecessor (1.2) and, as a result, the Swashbuckle config interface has undergone yet another overhaul. Checkout the transition guide if you're upgrading from a prior version.

Getting Started

There are currently two Nuget packages - the Core library (Swashbuckle.Core) and a convenience package (Swashbuckle) - that provides automatic bootstrapping. The latter is only applicable to regular IIS hosted Web APIs. For all other hosting environments, you should only install the Core library and then follow the instructions below to manually enable the Swagger routes.

Once installed and enabled, you should be able to browse the following Swagger docs and UI endpoints respectively:

<your-root-url>/swagger/docs/v1

<your-root-url>/swagger

IIS Hosted

If your service is hosted in IIS, you can start exposing Swagger docs and a corresponding swagger-ui by simply installing the following Nuget package:

Install-Package Swashbuckle

This will add a reference to Swashbuckle.Core and also install a bootstrapper (App_Start/SwaggerConfig.cs) that enables the Swagger routes on app start-up using WebActivatorEx.

Self-hosted

If your service is self-hosted, just install the Core library:

Install-Package Swashbuckle.Core

Then manually enable the Swagger docs and, optionally, the swagger-ui by invoking the following extension methods (in namespace Swashbuckle.Application) on an instance of HttpConfiguration (e.g. in Program.cs)

httpConfiguration
     .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API"))
     .EnableSwaggerUi();

OWIN

If your service is hosted using OWIN middleware, just install the Core library:

Install-Package Swashbuckle.Core

Then manually enable the Swagger docs and swagger-ui by invoking the extension methods (in namespace Swashbuckle.Application) on an instance of HttpConfiguration (e.g. in Startup.cs)

httpConfiguration
    .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API"))
    .EnableSwaggerUi();    

Troubleshooting

Troubleshooting??? I thought this was all supposed to be "seamless"? OK you've called me out! Things shouldn't go wrong, but if they do, take a look at the FAQs for inspiration.

Customizing the Generated Swagger Docs

The following snippet demonstrates the minimum configuration required to get the Swagger docs and swagger-ui up and running:

httpConfiguration
      .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API"))
      .EnableSwaggerUi();

These methods expose a range of configuration and extensibility options that you can pick and choose from, combining the convenience of sensible defaults with the flexibility to customize where you see fit. Read on to learn more.

Custom Routes

The default route templates for the Swagger docs and swagger-ui are "swagger/docs/{apiVersion}" and "swagger/ui/{*assetPath}" respectively. You're free to change these so long as the provided templates include the relevant route parameters - {apiVersion} and {*assetPath}.

httpConfiguration
    .EnableSwagger("docs/{apiVersion}/swagger", c => c.SingleApiVersion("v1", "A title for your API"))
    .EnableSwaggerUi("sandbox/{*assetPath}");

In this case the URL to swagger-ui will be sandbox/index.

Pretty Print

If you want the output Swagger docs to be indented properly, enable the PrettyPrint option as following:

httpConfiguration
    .EnableSwagger(c => c.PrettyPrint())
    .EnableSwaggerUi();

Additional Service Metadata

In addition to operation descriptions, Swagger 2.0 includes several properties to describe the service itself. These can all be provided through the configuration API:

httpConfiguration
    .EnableSwagger(c =>
        {
            c.RootUrl(req => GetRootUrlFromAppConfig());

            c.Schemes(new[] { "http", "https" });

            c.SingleApiVersion("v1", "Swashbuckle.Dummy")
                .Description("A sample API for testing and prototyping Swashbuckle features")
                .TermsOfService("Some terms")
                .Contact(cc => cc
                    .Name("Some contact")
                    .Url("http://tempuri.org/contact")
                    .Email("[email protected]"))
                .License(lc => lc
                    .Name("Some License")
                    .Url("http://tempuri.org/license"));
        });

RootUrl

By default, the service root url is inferred from the request used to access the docs. However, there may be situations (e.g. proxy and load-balanced environments) where this does not resolve correctly. You can workaround this by providing your own code to determine the root URL.

Schemes

If schemes are not explicitly provided in a Swagger 2.0 document, then the scheme used to access the docs is taken as the default. If your API supports multiple schemes and you want to be explicit about them, you can use the Schemes option.

SingleApiVersion

Use this to describe a single version API. Swagger 2.0 includes an "Info" object to hold additional metadata for an API. Version and title are required but you may also provide additional fields as shown above.

NOTE: If your Web API is hosted in IIS, you should avoid using full-stops in the version name (e.g. "1.0"). The full-stop at the tail of the URL will cause IIS to treat it as a static file (i.e. with an extension) and bypass the URL Routing Module and therefore, Web API.

Describing Multiple API Versions

If your API has multiple versions, use MultipleApiVersions instead of SingleApiVersion. In this case, you provide a lambda that tells Swashbuckle which actions should be included in the docs for a given API version. Like SingleApiVersion, Version also returns an "Info" builder so you can provide additional metadata per API version.

httpConfiguration
    .EnableSwagger(c =>
        {
            c.MultipleApiVersions(
                (apiDesc, targetApiVersion) => ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion),
                (vc) =>
                {
                    vc.Version("v2", "Swashbuckle Dummy API V2");
                    vc.Version("v1", "Swashbuckle Dummy API V1");
                });
        });
    .EnableSwaggerUi(c =>
        {
            c.EnableDiscoveryUrlSelector();
        });

* You can also enable a select box in the swagger-ui (as shown above) that displays a discovery URL for each version. This provides a convenient way for users to browse documentation for different API versions.

Describing Security/Authorization Schemes

You can use BasicAuth, ApiKey or OAuth2 options to describe security schemes for the API. See https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md for more details.

httpConfiguration
     .EnableSwagger(c =>
         {
             //c.BasicAuth("basic")
             //    .Description("Basic HTTP Authentication");

             //c.ApiKey("apiKey")
             //    .Description("API Key Authentication")
             //    .Name("apiKey")
             //    .In("header");

             c.OAuth2("oauth2")
                 .Description("OAuth2 Implicit Grant")
                 .Flow("implicit")
                 .AuthorizationUrl("http://petstore.swagger.wordnik.com/api/oauth/dialog")
                 //.TokenUrl("https://tempuri.org/token")
                 .Scopes(scopes =>
                 {
                     scopes.Add("read", "Read access to protected resources");
                     scopes.Add("write", "Write access to protected resources");
                 });

             c.OperationFilter<AssignOAuth2SecurityRequirements>();
         });
     .EnableSwaggerUi(c =>
         {
             c.EnableOAuth2Support("test-client-id", "test-realm", "Swagger UI");
         });

NOTE: These only define the schemes and need to be coupled with a corresponding "security" property at the document or operation level to indicate which schemes are required for each operation. To do this, you'll need to implement a custom IDocumentFilter and/or IOperationFilter to set these properties according to your specific authorization implementation

* If your API supports the OAuth2 Implicit flow, and you've described it correctly, according to the Swagger 2.0 specification, you can enable UI support as shown above.

Customize the Operation Listing

If necessary, you can ignore obsolete actions and provide custom grouping/sorting strategies for the list of Operations in a Swagger document:

httpConfiguration
    .EnableSwagger(c =>
        {
            c.IgnoreObsoleteActions();

            c.GroupActionsBy(apiDesc => apiDesc.HttpMethod.ToString());

            c.OrderActionGroupsBy(new DescendingAlphabeticComparer());
        });

IgnoreObsoleteActions

Set this flag to omit operation descriptions for any actions decorated with the Obsolete attribute

NOTE: If you want to omit specific operations but without using the Obsolete attribute, you can create an IDocumentFilter or make use of the built in ApiExplorerSettingsAttribute

GroupActionsBy

Each operation can be assigned one or more tags which are then used by consumers for various reasons. For example, the swagger-ui groups operations according to the first tag of each operation. By default, this will be the controller name but you can use this method to override with any value.

OrderActionGroupsBy

You can also specify a custom sort order for groups (as defined by GroupActionsBy) to dictate the order in which operations are listed. For example, if the default grouping is in place (controller name) and you specify a descending alphabetic sort order, then actions from a ProductsController will be listed before those from a CustomersController. This is typically used to customize the order of groupings in the swagger-ui.

Modifying Generated Schemas

Swashbuckle makes a best attempt at generating Swagger compliant JSON schemas for the various types exposed in your API. However, there may be occasions when more control of the output is needed. This is supported through the following options:

httpConfiguration
      .EnableSwagger(c =>
          {
              c.MapType<ProductType>(() => new Schema { type = "integer", format = "int32" });

              c.SchemaFilter<ApplySchemaVendorExtensions>();

              //c.UseFullTypeNameInSchemaIds();

              c.SchemaId(t => t.FullName.Contains('`') ? t.FullName.Substring(0, t.FullName.IndexOf('`')) : t.FullName);
              
              c.IgnoreObsoleteProperties();

              c.DescribeAllEnumsAsStrings();
          });

MapType

Use this option to override the Schema generation for a specific type.

It should be noted that the resulting Schema will be placed "inline" for any applicable Operations. While Swagger 2.0 supports inline definitions for "all" Schema types, the swagger-ui tool does not. It expects "complex" Schemas to be defined separately and referenced. For this reason, you should only use the MapType option when the resulting Schema is a primitive or array type.

If you need to alter a complex Schema, use a Schema filter.

SchemaFilter

If you want to post-modify "complex" Schemas once they've been generated, across the board or for a specific type, you can wire up one or more Schema filters.

ISchemaFilter has the following interface:

void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type);

A typical implementation will inspect the system Type and modify the Schema accordingly. If necessary, the schemaRegistry can be used to obtain or register Schemas for other Types

UseFullTypeNamesInSchemaIds

In a Swagger 2.0 document, complex types are typically declared globally and referenced by unique Schema Id. By default, Swashbuckle does NOT use the full type name in Schema Ids. In most cases, this works well because it prevents the "implementation detail" of type namespaces from leaking into your Swagger docs and UI. However, if you have multiple types in your API with the same class name, you'll need to opt out of this behavior to avoid Schema Id conflicts.

SchemaId

Use this option to provide your own custom strategy for inferring SchemaId's for describing "complex" types in your API.

IgnoreObsoleteProperties

Set this flag to omit schema property descriptions for any type properties decorated with the Obsolete attribute

DescribeAllEnumsAsStrings

In accordance with the built in JsonSerializer, Swashbuckle will, by default, describe enums as integers. You can change the serializer behavior by configuring the StringEnumConverter globally or for a given enum type. Swashbuckle will honor this change out-of-the-box. However, if you use a different approach to serialize enums as strings, you can also force Swashbuckle to describe them as strings.

Modifying Generated Operations

Similar to Schema filters, Swashbuckle also supports Operation and Document filters:

httpConfiguration
     .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API"))
         {
             c.OperationFilter<AddDefaultResponse>();

             c.DocumentFilter<ApplyDocumentVendorExtensions>();
         });

OperationFilter

Post-modify Operation descriptions once they've been generated by wiring up one or more Operation filters.

IOperationFilter has the following interface:

void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription);

A typical implementation will inspect the ApiDescription and modify the Operation accordingly. If necessary, the schemaRegistry can be used to obtain or register Schemas for Types that are used in the Operation.

DocumentFilter

Post-modify the entire Swagger document by wiring up one or more Document filters.

IDocumentFilter has the following interface:

void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer);

This gives full control to modify the final SwaggerDocument. You can gain additional context from the provided SwaggerDocument (e.g. version) and IApiExplorer. You should have a good understanding of the Swagger 2.0 spec. before using this option.

Wrapping the SwaggerGenerator with Additional Behavior

The default implementation of ISwaggerProvider, the interface used to obtain Swagger metadata for a given API, is the SwaggerGenerator. If neccessary, you can inject your own implementation or wrap the existing one with additional behavior. For example, you could use this option to inject a "Caching Proxy" that attempts to retrieve the SwaggerDocument from a cache before delegating to the built-in generator:

httpConfiguration
      .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API"))
          {
        c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider));
          });

Including XML Comments

If you annotate Controllers and API Types with Xml Comments, you can incorporate those comments into the generated docs and UI. The Xml tags are mapped to Swagger properties as follows:

  • Action summary -> Operation.summary
  • Action remarks -> Operation.description
  • Parameter summary -> Parameter.description
  • Type summary -> Schema.descripton
  • Property summary -> Schema.description (i.e. on a property Schema)

You can enable this by providing the path to one or more XML comments files:

httpConfiguration
    .EnableSwagger(c =>
        {
            c.SingleApiVersion("v1", "A title for your API");
            c.IncludeXmlComments(GetXmlCommentsPathForControllers());
            c.IncludeXmlComments(GetXmlCommentsPathForModels());
        });

NOTE: You will need to enable output of the XML documentation file. This is enabled by going to project properties -> Build -> Output. The "XML documentation file" needs to be checked and a path assigned, such as "bin\Debug\MyProj.XML". You will also want to verify this across each build configuration. Here's an example of reading the file, but it may need to be modified according to your specific project settings:

httpConfiguration
    .EnableSwagger(c =>
        {
            var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
            var commentsFileName = Assembly.GetExecutingAssembly().GetName().Name + ".XML";
            var commentsFile = Path.Combine(baseDirectory, commentsFileName);

            c.SingleApiVersion("v1", "A title for your API");
            c.IncludeXmlComments(commentsFile);
            c.IncludeXmlComments(GetXmlCommentsPathForModels());
        });

Response Codes

Swashbuckle will automatically create a "success" response for each operation based on the action's return type. If it's a void, the status code will be 204 (No content), otherwise 200 (Ok). This mirrors WebApi's default behavior. If you need to change this and/or list additional response codes, you can use the non-standard "response" tag:

/// <response code="201">Account created</response>
/// <response code="400">Username already in use</response>
public int Create(Account account)

Working Around Swagger 2.0 Constraints

In contrast to Web API, Swagger 2.0 does not include the query string component when mapping a URL to an action. As a result, Swashbuckle will raise an exception if it encounters multiple actions with the same path (sans query string) and HTTP method. You can workaround this by providing a custom strategy to pick a winner or merge the descriptions for the purposes of the Swagger docs

httpConfiguration
    .EnableSwagger((c) =>
        {
            c.SingleApiVersion("v1", "A title for your API"));
            c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
        });

See the following discussion for more details:

#142

Customizing the swagger-ui

The swagger-ui is a JavaScript application hosted in a single HTML page (index.html), and it exposes several customization settings. Swashbuckle ships with an embedded version and includes corresponding configuration methods for each of the UI settings. If you require further customization, you can also inject your own version of "index.html". Read on to learn more.

Customizations via the configuration API

If you're happy with the basic look and feel but want to make some minor tweaks, the following options may be sufficient:

httpConfiguration
    .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API"))
    .EnableSwaggerUi(c =>
        {
            c.InjectStylesheet(containingAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testStyles1.css");
            c.InjectJavaScript(containingAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testScript1.js");
            c.SetValidatorUrl("http://localhost/validator");
            c.DisableValidator();
            c.DocExpansion(DocExpansion.List);
            c.SupportedSubmitMethods("GET", "HEAD")
        });

InjectStylesheet

Use this to enrich the UI with one or more additional CSS stylesheets. The file(s) must be included in your project as an "Embedded Resource", and then the resource's "Logical Name" is passed to the method as shown above. See Injecting Custom Content for step by step instructions.

InjectJavaScript

Use this to invoke one or more custom JavaScripts after the swagger-ui has loaded. The file(s) must be included in your project as an "Embedded Resource", and then the resource's "Logical Name" is passed to the method as shown above. See Injecting Custom Content for step by step instructions.

SetValidatorUrl/DisableValidator

By default, swagger-ui will validate specs against swagger.io's online validator and display the result in a badge at the bottom of the page. Use these options to set a different validator URL or to disable the feature entirely.

DocExpansion

Use this option to control how the Operation listing is displayed. It can be set to "None" (default), "List" (shows operations for each resource), or "Full" (fully expanded: shows operations and their details).

SupportedSubmitMethods

Specify which HTTP operations will have the 'Try it out!' option. An empty parameter list disables it for all operations.

Provide your own "index" file

As an alternative, you can inject your own version of "index.html" and customize the markup and swagger-ui directly. Use the CustomAsset option to instruct Swashbuckle to return your version instead of the default when a request is made for "index". As with all custom content, the file must be included in your project as an "Embedded Resource", and then the resource's "Logical Name" is passed to the method as shown below. See Injecting Custom Content for step by step instructions.

For compatibility, you should base your custom "index.html" off this version

httpConfiguration
     .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API"))
     .EnableSwaggerUi(c =>
         {
             c.CustomAsset("index", yourAssembly, "YourWebApiProject.SwaggerExtensions.index.html");
         });

Injecting Custom Content

The InjectStylesheet, InjectJavaScript and CustomAsset options all share the same mechanism for providing custom content. In each case, the file must be included in your project as an "Embedded Resource". The steps to do this are described below:

  1. Add a new file to your Web API project.
  2. In Solution Explorer, right click the file and open its properties window. Change the "Build Action" to "Embedded Resource".

This will embed the file in your assembly and register it with a "Logical Name". This can then be passed to the relevant configuration method. It's based on the Project's default namespace, file location and file extension. For example, given a default namespace of "YourWebApiProject" and a file located at "/SwaggerExtensions/index.html", then the resource will be assigned the name - "YourWebApiProject.SwaggerExtensions.index.html". If you use "Swagger" as the root folder name for your custom assets, this will collide with the default route templates and the page will not be loaded correctly.

Transitioning to Swashbuckle 5.0

This version of Swashbuckle makes the transition to Swagger 2.0. The 2.0 specification is significantly different to its predecessor (1.2) and forces several breaking changes to Swashbuckle's configuration API. If you're using Swashbuckle without any customizations, i.e. App_Start/SwaggerConfig.cs has never been modified, then you can overwrite it with the new version. The defaults are the same and so the swagger-ui should behave as before.

* If you have consumers of the raw Swagger document, you should ensure they can accept Swagger 2.0 before making the upgrade.

If you're using the existing configuration API to customize the final Swagger document and/or swagger-ui, you will need to port the code manually. The static Customize methods on SwaggerSpecConfig and SwaggerUiConfig have been replaced with extension methods on HttpConfiguration - EnableSwagger and EnableSwaggerUi. All options from version 4.0 are made available through these methods, albeit with slightly different naming and syntax. Refer to the tables below for a summary of changes:

4.0 5.0 Equivalent Additional Notes
ResolveBasePathUsing RootUrl
ResolveTargetVersionUsing N/A version is now implicit in the docs URL e.g. "swagger/docs/{apiVersion}"
ApiVersion SingleApiVersion now supports additional metadata for the version
SupportMultipleApiVersions MultipleApiVersions now supports additional metadata for each version
Authorization BasicAuth/ApiKey/OAuth2
GroupDeclarationsBy GroupActionsBy
SortDeclarationsBy OrderActionGroupsBy
MapType MapType now accepts Func<Schema> instead of Func<DataType>
ModelFilter SchemaFilter IModelFilter is now ISchemaFilter, DataTypeRegistry is now SchemaRegistry
OperationFilter OperationFilter DataTypeRegistry is now SchemaRegistry
PolymorphicType N/A not currently supported
SupportHeaderParams N/A header params are implicitly supported
SupportedSubmitMethods N/A all HTTP verbs are implicitly supported
CustomRoute CustomAsset ย 

Troubleshooting and FAQ's

  1. Swagger-ui showing "Can't read swagger JSON from ..."
  2. Page not found when accessing the UI
  3. Swagger-ui broken by Visual Studio 2013
  4. OWIN Hosted in IIS - Incorrect VirtualPathRoot Handling
  5. How to add vendor extensions
  6. FromUri Query string DataMember names are incorrect
  7. Remove Duplicate Path Parameters
  8. Deploying behind Load Balancer / Reverse Proxies
  9. 500 : {"Message":"An error has occurred."}

Swagger-ui showing "Can't read swagger JSON from ..."

If you see this message, it means the swagger-ui received an unexpected response when requesting the Swagger document. You can troubleshoot further by navigating directly to the discovery URL included in the error message. This should provide more details.

If the discovery URL returns a 404 Not Found response, it may be due to a full-stop in the version name (e.g. "1.0"). This will cause IIS to treat it as a static file (i.e. with an extension) and bypass the URL Routing Module and therefore, Web API.

To workaround, you can update the version name specified in SwaggerConfig.cs. For example, to "v1", "1-0" etc. Alternatively, you can change the route template being used for the swagger docs (as shown here) so that the version parameter is not at the end of the route.

Page not found when accessing the UI

Swashbuckle serves an embedded version of the swagger-ui through the Web API pipeline. But, most of the URLs contain extensions (.html, .js, .css) and many IIS environments are configured to bypass the managed pipeline for paths containing extensions.

In previous versions of Swashbuckle, this was resolved by adding the following setting to your Web.config:

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

This is no longer neccessary in Swashbuckle 5.0 because it serves the swagger-ui through extensionless URL's.

However, if you're using the SingleApiVersion, MultipleApiVersions or CustomAsset configuration settings you could still get this error. Check to ensure you're not specifying a value that causes a URL with an extension to be referenced in the UI. For example a full-stop in a version number ...

httpConfiguration
    .EnableSwagger(c => c.SingleApiVersion("1.0", "A title for your API"))
    .EnableSwaggerUi();

will result in a discovery URL like this "/swagger/docs/1.0" where the full-stop is treated as a file extension.

Swagger-ui broken by Visual Studio 2013

VS 2013 ships with a new feature - Browser Link - that improves the web development workflow by setting up a channel between the IDE and pages being previewed in a local browser. It does this by dynamically injecting JavaScript into your files.

Although this JavaScript SHOULD have no affect on your production code, it appears to be breaking the swagger-ui.

I hope to find a permanent fix, but in the meantime, you'll need to workaround this issue by disabling the feature in your web.config:

<appSettings>
    <add key="vs:EnableBrowserLink" value="false"/>
</appSettings>

OWIN Hosted in IIS - Incorrect VirtualPathRoot Handling

When you host Web API 2 on top of OWIN/SystemWeb, Swashbuckle cannot correctly resolve VirtualPathRoot by default.

You must either explicitly set VirtualPathRoot in your HttpConfiguration at startup, or perform customization like this to fix automatic discovery:

httpConfiguration.EnableSwagger(c => 
{
    c.RootUrl(req =>
        req.RequestUri.GetLeftPart(UriPartial.Authority) +
        req.GetRequestContext().VirtualPathRoot.TrimEnd('/'));
}

How to add vendor extensions

Swagger 2.0 allows additional meta-data (aka vendor extensions) to be added at various points in the Swagger document. Swashbuckle supports this by including a "vendorExtensions" dictionary with each of the extensible Swagger types. Meta-data can be added to these dictionaries from custom Schema, Operation or Document filters. For example:

public class ApplySchemaVendorExtensions : ISchemaFilter
{
    public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
    {
        schema.vendorExtensions.Add("x-foo", "bar");
    }
}

As per the specification, all extension properties should be prefixed by "x-"

FromUri Query string DataMember names are incorrect

When using FromUri Model Binding, it is possible to override the querystring parameter name's using DataMembers. In this case you can add a custom operation filter to override the name. For example:

public class ComplexTypeOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        if (operation.parameters == null)
            return;

        var parameters = apiDescription.ActionDescriptor.GetParameters();
        foreach (var parameter in parameters)
        {
            foreach (var property in parameter.ParameterType.GetProperties())
            {
                var param = operation.parameters.FirstOrDefault(o => o.name.ToLowerInvariant().Contains(property.Name.ToLowerInvariant()));

                if (param == null) continue;

                var name = GetNameFromAttribute(property);

                if (string.IsNullOrEmpty(name))
                {
                    operation.parameters.Remove(param);
                }
                param.name = GetNameFromAttribute(property);
            }
        }
    }
    
    private static string GetNameFromAttribute(PropertyInfo property)
    {
        var customAttributes = property.GetCustomAttributes(typeof(DataMemberAttribute), true);
        if (customAttributes.Length > 0)
        {
            var attribute = customAttributes[0] as DataMemberAttribute;
            if (attribute != null) return attribute.Name;
        }
        return string.Empty;
    }
}

Remove Duplicate Path Parameters

When using FromUri Model Binding, duplicate items can appear as items can be passed as URI parameters, or querystrings. In this case you can add a custom operation filter to remove the duplicates. For example:

public class ComplexTypeOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
       if (operation.parameters == null)
           return;
       var complexParameters = operation.parameters.Where(x => x.@in == "query" && !string.IsNullOrWhiteSpace(x.name)).ToArray();

       foreach (var parameter in complexParameters)
       {
           if (!parameter.name.Contains('.')) continue;
           var name = parameter.name.Split('.')[1];

           var opParams = operation.parameters.Where(x => x.name == name);
           var parameters = opParams as Parameter[] ?? opParams.ToArray();

           if (parameters.Length > 0)
           {
               operation.parameters.Remove(parameter);
           }
       }
    }
}

Deploying behind Load Balancer / Reverse Proxies

Swashbuckle attempts to populate the Swagger "host" property from HTTP headers that are sent with the request for Swagger JSON. This may cause issues in load balancer / reverse proxy environments, particularly if non-standard headers are used to pass on the outer most host name. You can workaround this by providing your own function for determining your API's root URL based on vendor-specific headers. Checkout issue 705 for some potential implementations.

500 : {"Message":"An error has occurred."}

If, on loading the Swagger UI page, you get an error: 500 : {"Message":"An error has occurred."} http://<url>/swagger/docs/v1 ensure that the XML documentation output settings have been set in the project file in the solution, for both Debug and Release configurations.

swashbuckle.webapi's People

Contributors

304notmodified avatar andyalm avatar asemenel-softheme avatar bhugot avatar chris-peterson avatar chriseldredge avatar davetransom avatar daviddesloovere avatar domaindrivendev avatar gambrose avatar gislikonrad avatar gitfool avatar gordey4doronin avatar heldersepu avatar itnmike avatar jawn avatar kestrel12 avatar khorvat avatar manuelrauber avatar markmonster avatar mharen avatar mikaelbr avatar mladenb avatar munkeycigar avatar phil-scott-78 avatar robpex avatar smichtch avatar svickers avatar urig avatar vertiman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swashbuckle.webapi's Issues

Model-Schema not expanding to show contained types

Hi @domaindrivendev,

I am not sure, if this is an issue with swagger-ui or Swashbuckle. The Model-Schema does not do a second level description of contained models.

Eg:- For a model like this

{
  "PolicyKey": 0,
  "Revision": 0,
  "UpdatedInstances": [
       "PolicyInstanceBaseData"  
     ]
}

I think it should instead show something like the following:

{
  "PolicyKey": "integer",
  "Revision": "integer",
  "UpdatedInstances": "PolicyInstanceBaseData" [
      {
        "key": "integer",
        "id": "string",
        "enabled": "boolean",
        "mappingsComplete": "boolean"
      }
    ]
}

I tried to understand how model-schema is being generated, with little success. Can you please let me know how I can proceed with this?

Thank you!

swagger-ui gui population

first of all... AWESOME library. thanks for all your work here... :-)

so I'm getting started with swashbuckle and i'm fully up and running but i'm still admittedly a bit of a newbie here. My question now revolves around front end GUI population.

if you look here: http://petstore.swagger.wordnik.com/#!/pet/updatePet you'll see some fancy populated stuff like the Response Messages fields on the bottom... My question to you is if you can you point me to a full list of xml tags that will be presented at the swagger-ui level?

On a side note, I'm not sure if it's a bug or not, but only one of my response objects is being mapped out at the swagger-ui level. all other response object class models are just being presented in swagger as:

classname {
}

and they're all defined in the same exact ways in my code so that's a little weird. they also are fully populated in the webapi help docs as i would expect these models to be displayed in swagger-ui.

sorry for the general questions, but thanks in advance for any and all help :-)

Error creating Json-Spec for classes with index based properties

@domaindrivendev.

Branching out from issue#25,

What we have are some classes with index-properties of a certain type, with the an integer or string or culture based index.

public class SomeRandomClass
{       
    private LocalizedValue [] _values = null;

    public LocalizedValue this[int index]
    {
        get { return _values[index]; }
    }

    public LocalizedValue this[string cultureID]
    {
        get 
        {
            for (int i = 0; i < _values.Length; i++)
            {
                if (_values[i].CultureID.Equals(cultureID))
                    return _values[i];
            }

            return null;
        }
    }

    public LocalizedValue this[CultureInfo culture]
    {
        get
        {
            return this[culture.Name];
        }
    }
}

The propertyType - ModelSpec dictionary that you create while reflecting upon the class, considers just the return type of the properties as the key for the dictionary, which in the above case is "LocalizedValue" for all the three index based properties, and hence throws a duplicate key exception.

When swashbuckle generates a model-spec for such a class, it throws the same exception as in Issue#25.

image

I think you can get rid of index properties all together while reflecting, since they mean nothing in javascript.

var propInfos = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
                    .Where(propInfo => propInfo.GetIndexParameters().Length == 0);

Regards,
Venkat Renuka Prasad.

Inheritance Hierarchy not recognized by Swashbuckle?

Hello,
I have realized that in many cases, we use Inheritance hierarchy for certain items. For e.g. we have a base Field class that has a Title and a Key property. Then we have a TextField which derives from a Field class and adds a Description property. When swagger shows documentation for the TextField, it only shows Description as the property and doesn't recognize the underlying Title or Key as properties.

would you be able to look into this and guide me if I'm doing something incorrectly?

Thank You so much!

swashbuckle not swaggering!

I have an asp.net webapi running (.net 4.5) with Help pages loading all my xml comments via the ApiExplorer. I want to now add swagger via swashbuckle. So I installed the swashbuckle nuget but when I browse to my endpoint I get an error as suggested by swashbuckle documentation..

endpoint: localhost:1234/api/company/swagger error: {"Message":"Unauthorized request"} or endpoint: localhost:1234/api/company/swagger/apidocs error: 404 - Not Found

Am I missing a step or what am I doing wrong??

De-couple Swashbuckle.Core from Swagger-ui

Any chance the UI bits (and corresponding HTTP handler) can be pulled out into a separate NuGet package? We tend to host the docs in a separate site which points at the Swashbuckle endpoint. It also allows us to version swagger-ui without having to re-deploy our main app.

Error while generating json-spec for certain classes

Hi @domaindrivendev,

Swashbuckle threw a 500 - internal server error. I debugged and found, the error is while generating ModelSpec for certain classes.

Tracing it:

ModelSpecGenerator.TypeToModelSpec for a few particular types, when looping through to generate Complex-Spec for contained types, calls CreateSpecFor(..)
which in turn calls CreateComplexSpecFor()

private ModelSpec CreateComplexSpecFor(Type type, IDictionary<Type, ModelSpec> complexTypes)
{
        var propInfos = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);

        //This line throws the error: "An item with the same key has already been added"
        var propSpecs = propInfos
            .ToDictionary(propInfo => propInfo.Name, propInfo => CreateSpecFor(propInfo.PropertyType, true, complexTypes));
//.........
//.........
}

type {Name = "ApplicationTrustCollection" FullName = "System.Security.Policy.ApplicationTrustCollection"}

swashbuckle-error

Thank you.

Ability to replace index.html entirely

I'm working with the Swashbuckle.Core 4.0-beta package in an OWIN-hosted WebAPI project and it works pretty well.

One of the challenges, though, is that while I can inject scripts and CSS, I can't actually change the index.html file that easily. For example, I might want to put my own icon/buttons with their own destinations at the top of the page, or add some additional page content in there.

While I could probably retroactively "poke" it in with jQuery or something, it'd be nice to just be able to swap out the index.html entirely. Or make use of some sort of pseudo "master page" sort of thing where the page is actually built up from smaller templates for the header and footer that I could affect.

Swashbuckle and Azure

Hi,
I've encountered really strange bug.

I've included swashbuckle to our azure project. After deploy, the web role kept recycling.

After couple of hours of experimenting we've found the issue.
Just mere existence of AddStandardResponseCodes class in the project was the problem.

After removing this class, everything was ok.

Yes, even after commenting out line c.OperationFilter<AddStandardResponseCodes>); web role kept recycling. We had to remove the file from project.

If it will be any helpful this is the exception

[00000017] [06/05/2014 13:54:15.19] [WARN]  PutMachineHealth() failed, will retry later. Exception: Microsoft.ServiceModel.Web.WebProtocolException: Server Error: Internal Server Error (InternalServerError)

Server stack trace: 
   at Microsoft.ServiceModel.Dispatcher.WebHttpClientMessageFormatterEx.DeserializeReply(Message message, Object[] parameters)
   at System.ServiceModel.Dispatcher.ProxyOperationRuntime.AfterReply(ProxyRpc& rpc)
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at Microsoft.ServiceModel.Web.WebHttpChannelProxy`1.Invoke(IMessage msg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at Microsoft.WindowsAzure.RoleContainer.Protocol.IControlSystem.PutMachineHealth(Health health)
   at Microsoft.WindowsAzure.RoleContainer.Protocol.ControlSystemExtensions.PutMachineHealth(IControlSystem channel, Health health, Nullable`1& latestGoalStateIncarnationNumber)
   at Microsoft.WindowsAzure.RoleContainer.Protocol.ControlSystem.ReportHealth(Health health, Nullable`1& latestIncarnation).

JsonProperty and JsonIgnore

I'm using the JsonProperty("PropertyName") attribute to change my JSON property names, and the JsonIgnore attribute to ignore certain properties.

However Swashbuckle seems to be ignoring these when generating documentation.

Would it be a big job to implement this?

Newbie Question - Setup and Routing Raw Data

I have a somewhat unique setup due to numerous teams developing Web APIs on the same server. We have one main project that runs our web app (and contains the App_Start), sets up routing rules, configuration, etc. There are also a number of MVC and Web API projects that each contain one or more controllers. Example:

Solution 'WebProjects'

  • MainWebAppProj
  • TeamAMVC
  • TeamBMVC
  • TeamAWebAPI
  • TeamBWebAPI
  • TeamCMVC
  1. If I want the project "TeamAWebAPI" to be documented with Swagger using Swashbuckle, where should I install the Nuget package so that it starts Swashbuckle properly in the web app, but can also detect my web api project as an API that needs swagger documentation?

  2. When I have installed Swashbuckle in the past, I could only ever access it on localhost. My web api has a domain constraint that limits it "api.MYDOMAIN.com." How do I route the raw data to the domain in the domain constraint?

Thanks!

NullReferenceException

Using Swashbuckle, I'm getting a NullRef when its trying to describe one of my ApiControllers:

{"message":"An error has occurred.","exceptionMessage":"Object reference not set to an instance of an object.","exceptionType":"System.NullReferenceException","stackTrace":" at Swashbuckle.Swagger.OperationGenerator.CreateParameter(ApiParameterDescription apiParamDesc, String apiPath)\r\n at Swashbuckle.Swagger.OperationGenerator.<>c__DisplayClass2.b__1(ApiParameterDescription paramDesc)\r\n at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()\r\n at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\r\n at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)\r\n at Swashbuckle.Swagger.OperationGenerator.ApiDescriptionToOperation(ApiDescription apiDescription)\r\n at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()\r\n at System.Linq.Buffer`1..ctor(IEnumerable`1 source)\r\n at System.Linq.OrderedEnumerable`1.d__0.MoveNext()\r\n at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\r\n at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)\r\n at Swashbuckle.Swagger.ApiExplorerAdapter.CreateApi(IGrouping`2 apiDescriptionGroup, OperationGenerator operationGenerator)\r\n at Swashbuckle.Swagger.ApiExplorerAdapter.<>c__DisplayClassb.b__7(IGrouping`2 apiDescGrp)\r\n at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()\r\n at System.Linq.Buffer`1..ctor(IEnumerable`1 source)\r\n at System.Linq.OrderedEnumerable`1.d__0.MoveNext()\r\n at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\r\n at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)\r\n at Swashbuckle.Swagger.ApiExplorerAdapter.GetDeclaration(String basePath, String version, String resourceName)\r\n at Swashbuckle.Application.CachingSwaggerProvider.<>c__DisplayClass4.b__3(String k)\r\n at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)\r\n at Swashbuckle.Application.CachingSwaggerProvider.GetDeclaration(String basePath, String version, String resourceName)\r\n at Swashbuckle.Application.SwaggerSpecHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Web.Http.HttpServer.<>n__FabricatedMethod9(HttpRequestMessage , CancellationToken )\r\n at System.Web.Http.HttpServer.d__0.MoveNext()"}

Inherited properties not included in ModelSpec

A few months back, a change was made so that only declared properties are included in the ModelSpec. Now several of my classes that inherit from a base class no longer show all their properties in the swagger description.
The change was in this commit: a8e84cc

Signing the assembly..

Hi @domaindrivendev,

We're signing all our assemblies used in our project. Swashbuckle doesn't seem to be signed. Can you please release a signed version of Swashbuckle?

Thanks,
Venkat.

swagger-ui containment

disclaimer: i'm still new to dot-net land so bear with me for just a minute... :-)

so the default path to swagger(which i beautifully have fully up and running and integrated with my api's) is ~/swagger/ui/index.html. What i have thus far done is created a Controller that just spits back View(). This view has an iframe in it that contains the path to swagger-ui... the problem there being that now i've got nested scrollbars and, well, it's an iframe and that's no fun. what i would like to do is have swagger-ui as the source of the Controller and drop the iframe garbage. would this be feasible?

so far i've had two ideas as to how this would be accomplished and not sure if they're doable so figured the experts over here might have a good idea of how to proceed...

  1. at the swagger level, reroute the swagger/ui/index.html to something in more of a proper path of what the Controller would be able to automatically pick up...
  2. in the project, somehow configure the view path that the Controller looks to, to something like the swagger/ui/index.html instead of the index.cshtml that it automatically looks for in its respective folder

would either of these be ideal or even work? i figured an issue was an appropriate place since this would be an awesome readme topic... :-)

thanks for the awesome library!

Descrining the Response Class when we wrap our return object in IHttpActionResult

If we wrap our actual return object in IHttpActionResult as a recommended practice in ASP.NET WebAPI 2, the Swagger Spec rather shows the Response Class as the top level interface for the IHttpActionResult.

Instead of that, I would like to describe the underlying class which, I plan to pick from the < returns > tag in the XML descriptive comments..

Any suggestions on where I could get started would be greatly appreciated.

Embedding ApiKey as a Bearer Token

Hello,
I understand that Swagger allows you to customize the API Key change event to allow adding the key as a part of the Header instead of the Query string parameter by changing the default code shown here:

$('#input_apiKey').change(function() {
var key = $('#input_apiKey')[0].value;
log("key: " + key);
if(key && key.trim() != "") {
log("added key " + key);
window.authorizations.add("key", new ApiKeyAuthorization("api_key", key, "query"));
}
})

I know the solution but I don't know how I can change this using Swashbuckle because the template is embedded. I noticed that you have a way to embed Javascript by creating Embedded resource files.

Can you please explain how we could go about doing this? I literally need to make the following change:

$('#input_apiKey').change(function () {
var key = $('#input_apiKey')[0].value;
if (key && key.trim() != "") {
key = "Bearer " + key;
window.authorizations.add("key", new ApiKeyAuthorization("Authorization", key, "header"));
}
})

I would highly appreciate it if you could guide me here.

Thanks in advance for your consideration.

Can we have a tree view like structure in the UI?

Hi @domaindrivendev,

We have a pretty large project with a large number of ApiControllers, that could go as high as 500 or more, which are spread across various areas.

Would it be too much work to group ApiDescriptionGroups by the namespace of the ApiController and render some kind of a tree view explorer in the ui?

Update Swashbuckle to work with Web API 2

I tried integrating Swashbuckle into a Web API 2 project and I can't seem to get the swagger UI to render correctly. I was optimistic since I thought the XML doc should be similar, but I notice that version 4.0 WebAPI assemblies are being referenced instead of the version 5.0 Web API 2 ones.

Not sure if branch remove_mvc_dependency would do anything to address this. I did try to drop in the dlls from that branch and started getting 404 errors where before I at least had the swagger headers. (I was guessing at the integration, so I may have blotched that one)

Infinite loop in JObject

I have the following signature in an API Controller:

        [System.Web.Http.AcceptVerbs("PUT")]
        public HttpResponseMessage Reorder(int itemid, 
            int parentid, 
            [FromBody] JObject jobject)
        { 
              //...
        }

It looks like the SwaggerGenerator goes into an infinite loop when it tries to reflect that method:

var modelSpec = modelSpecMap.FindOrCreateFor(parameterDescription.ParameterDescriptor.ParameterType);

That calls CreateContainerSpec, which calls CreateModelSpec, which calls CreateContainerSpec ad infinitum. The System.Type it's getting is a JToken:

if (type.IsEnumerable(out enumerableTypeArgument))
                return CreateContainerSpec(enumerableTypeArgument);

Eliminate MVC dependency

Hi, would it be possible to eliminate dependency on the MVC framework?

I was trying to use Swashbuckle on a project that has Aspnet Webforms Web Application + Aspnet Webapi (A legacy project that we are adding a REST api). The problem is that the path /swagger and /swagger/ui/index.html they both return 404.

Aspnet Webapi can be used on the top of MVC or ASPNet form. So it would be great if Swashbuckle could be used the same way.

Great job by the way!
Regads,
Victor

When I run the swashbuckle I get below error?

Hi I am very new and trying to learn how swashbuckle works. I started running the project 'Swashbuckle.Dummy.SelfHost' by downloading swash buckle. Then I went to the browser and checked the url that is given in main function of program.cs class. There after I get below error when I type the url in browser something linke 'http:/localhost:8090/swagger'. Can any one please guide me the step by step process to run the swash buckle solution and test it. If I want to host this application on IIS and run. Which folder do I need to host on IIS?

An error has occurred. Could not load file or assembly 'System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) System.IO.FileLoadException at Swashbuckle.Application.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.DelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Web.Http.HttpServer.<>n__FabricatedMethod9(HttpRequestMessage , CancellationToken ) at System.Web.Http.HttpServer.d__0.MoveNext()

Any RedirectToAction call is landing me on the swagger area

If I create a new mvc4 project and add in the latest published nuget package, any regular mvc controller with a RedirectToAction call is sending me to /swagger?controller=&action=

I'm using a stock VS 2012 MVC4 template, without change to any routes, etc.
If I comment out the AreaRegistration.RegisterAllAreas(); call in app startup, the problem disappears. Something is odd about the routing, but I can't find it.

Web API 2 using Owin middle-ware

Thanks for this interesting project, I've tried to integrate your plugin with this web API 2 https://github.com/tjoudeh/AngularJSAuthentication/tree/master/AngularJSAuthentication.API which is IIS hosted and uses owin middleware but It didn't work out correctly.

What I've done is the following:
Once I Moved Swashbuckle.Bootstrapper.Init(config); to owin Startup class and commented out the implementation in SwaggerConfig file the url http://localhost:26264/swagger/api-docs returned list of the API but there was no UI (it returns 404).
Once I kept calling Swashbuckle.Bootstrapper.Init(config) from 2 places (Startup & SwaggerConfig) classes it worked correctly but I believe it is not correct to fire up the init method twice.

It will be great if you were able to check my API and tell me what is the right to integrate it using Web API 2 with own middle ware.

2 newbie question about having different version documentation

Hi,
I implemented in web api 2 versioning based on namespaces,based on http://blogs.msdn.com/b/webdev/archive/2013/03/08/using-namespaces-to-version-web-apis.aspx implementations.
Documentation now generated in root/swwagger.
Is any way to generate documentation in root/v1/swagger? If so, how can i do it?

Also, my web api accessible by root/api/, but your implementation access root/swagger. Is any way to access it by going root/api/swagger?

Thank you

Swagger UI fails to load API for 1 controller

I have a number of API controllers that are being documented by Swagger/Swashbuckle. I'm finding that, for one of these controllers (named DataController i.e. my Web API route prefix is api/data), Swagger seems to refuse to generate documentation for the controller:

image
image

The error in loading this particular Swagger definition means that it is not possible to generate Swagger UI for the remaining controllers either, even though the Swagger JSON definitions are successfully being loaded for these controllers.

On the server side, I can see that the following error occurs whenever a GET request is made to the failing URL:

An exception occurred while processing an API request: GET http://localhost/Framework/swagger/api-docs/Data
System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at System.Web.Http.HttpServer.<SendAsync>d__0.MoveNext()

Thanks in advance for any guidance that you can offer!

Using Type.ShortName() in ModelSpecGenerator.UniqueIdFor causing collisions

We have an API that returns 2 representations of the same data - Basic and Verbose. Basic returning fewer fields. The classes behind these are named the same, but are in different namespaces.

When the Unique ID is created using the name it is not unique though as it is just using the class name and not the fully qualified name with the namespace.

We have managed to work around this but feel the full name would be more appropriate for a unique ID.

Doesn't add UI

I've tried adding this now a few times to my API project and it adds the .dll but no corresponding UI. I've tried copying in the UI files from the swagger site, but can't figure out how the routes are supposed to work. Any suggestions?

An item with the same key has already been added.

I have updated from version 2.2.1 to 3.0.1 and this version doesn't work.
Swagger can't load some data from site.

URL
http://localhost/WebAPI/swagger/api-docs

RESPONSE
An item with the same key has already been added.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ArgumentException: An item with the same key has already been added.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[ArgumentException: An item with the same key has already been added.]
System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) +52
System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boolean add) +10695474 System.Linq.Enumerable.ToDictionary(IEnumerable1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer) +247 Swashbuckle.Models.SwaggerGenerator.GenerateDeclaration(IGrouping2 apiDescriptionGroup) +515
System.Linq.Enumerable.ToDictionary(IEnumerable1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer) +235
Swashbuckle.Models.SwaggerGenerator.GenerateDeclarations(IEnumerable`1 apiDescriptionGroups) +134
Swashbuckle.Models.SwaggerGenerator.Generate(IApiExplorer apiExplorer) +227
Swashbuckle.Controllers.ApiDocsController..ctor() +117

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +113
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232
System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
System.Activator.CreateInstance(Type type) +6
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +55

[InvalidOperationException: An error occurred when trying to create a controller of type 'Swashbuckle.Controllers.ApiDocsController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +179
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +74
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +197
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +49
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

Sample App

Hello, we are currently building out our web api in VS 2012. Your project looks very interesting. I downloaded Swashbuckle.TestApp and I can't seem to get it to work. After fixing the Nuget warnings, it doesn't seem to resolve the index.html properly.

System.IO.FileNotFoundException: index.html
Swashbuckle-master\Swashbuckle\Handlers\EmbeddedResourceHttpHandler.cs Line: 33

I had to adjust the port number, but that shouldn't matter.

http://localhost:60888/swagger

Is there something I am missing? Or is this project still getting off the ground?

Custom per request auth header

Hey! We've had a great time with swashbuckle but we're having some trouble setting up custom auth headers that are unique to every call. We'll need to hash the request path, method and an API key. Ideally we'd like to just override the SwaggerHttp.prototype.execute (swagger.js line ~1137) which has all the information we need. Is there an easy way to monkeypatch that call from the custom script injection that swashbuckle uses?

How to sort methods by path?

Hi
Is it possible to add functionality to sort methods by path. For example: I have a lot of methods and it is not easy to search the method.(see attached image).

methods_path

Many thanks
Maksim

Relative path for UI request URL-s

Hi,

Is it possible to turn on relative path resolver for Swagger UI request URL-s or can it be implemented ?

I have a server that uses many load balancers. And because of it I can get swagger UI index page work well, but when trying to call any method, request are made to wrong base path and port.

For example, using load balancer, index page can be found from:
http://localhost:8401/swagger/ui/index.html
But when making any query, following path is used:
http://localhost:8450/api/Status

Can you please support the chance to use relative paths that can be used instead of configured path (automatically or manually) on App_start register ?

Model Properties - Default Values

Hi, First of all, brilliant work. I'm new to Swagger and Swashbuckle made life very easy for us to integrate into our API, a few well written comments later and we're good.

We are facing one minor issue in which our models assume default values which don't look that appealing. See the image attached.

default-values

Is there a way to specify a default value for model properties? I have had no luck using default value attributes so far e.g.

[System.ComponentModel.DefaultValue("My Default String Value")]
public string Value { get; set; }

query params incorrectly marked as path parameters

If a parameter that is from the uri has a name that is anywhere in the path, that parameter is marked as "path" even if it should really come from "query". For instance, if the apiPath is "api/v1/Swashbuckle" the parameter "wash" would be marked as "path" since it is found in the word Swashbuckle. When the parameter does come from the path, the parameter is surrounded by {} ({ParamName}). I think it would make sense to make this change to OperartionSpecGenerator.CreateParameterSpec(...)

case ApiParameterSource.FromUri:
    paramType = apiPath.Contains(apiParamDesc.Name) ? "path" : "query";
    break;

To be

case ApiParameterSource.FromUri:
    //Path parameters are surrounded by {} like this: {Param}
    paramType = apiPath.Contains(String.Concat('{',apiParamDesc.Name,'}')) ? "path" : "query";
    break;

HttpResponseMessage

Hi there,
Absolutely love the work you have done with this. I have evaluated both this and swagger.net, and I just had more success with this project.

Can I suggest the following modificaition. When we return HttpResponseMessage from the action, could Swashbuckle treat that as a "void" swagger datatype.

Thanks again for the hard work

Attribute Routing/Web API 2.0

Hello,
First of all, thank you for this project. Love it! I tried installing this with a Web API project that doesn't use Attribute routing and everything works great. However, upon installing this package on a Web API project that uses Attribute Routing throws an error like so:

Unable to read api 'AffiliatesV1' from path http://localhost:56251/swagger/api-docs/AffiliatesV1 (server returned undefined)

Where Affiliates is just the name of my controller. Going down the error, I see the error message as shown below. If I look at the RAW option on each API, I can see the correct items, however, this error is preventing me from viewing any operations etc.

Could you assist? Thanks!

message: "An error has occurred.",
exceptionMessage: "Object reference not set to an instance of an object.",
exceptionType: "System.NullReferenceException",
stackTrace: " at Swashbuckle.Swagger.OperationGenerator.CreateParameter(ApiParameterDescription apiParamDesc, String apiPath)
at Swashbuckle.Swagger.OperationGenerator.<>c__DisplayClass2.b__1(ApiParameterDescription paramDesc)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()

Swagger.js fails on getting signature for Object[ObjectOrValueType]

I just found Swashbuckle and was trying to use it out of the box to improve my API documentation. First thing I noticed is there is a JS error when trying to find a signature for a type. The issue is when you have a Model that is of SomeObject in WebApi. This causes issues in mapping because the isListType function in Swagger.js searches for "[" to determine if it is a list and then tries to find the that was used in the list of models. However in the list of Models, SomeObject[String] is listed so the mapping fails.

Question From a new Programmer

This is probably below the scope of your project, but it interested me and since I'm trying to broaden my horizons as a programmer, I figured it wouldn't hurt to ask. I'm in the process of trying to create my own MVC Web API project (something that I am still getting my feet wet with) and I wanted to utilize your project to create a swagger compliant spec from my code, but I don't want the JSON to go to a swagger-ui webpage. I want to output directly to a file. Is this possible?

Also, for various reasons, I am unable to use nuget to install your project. How would I go about installing this manually?

Thank you for your time, I appreciate any help you can provide!

ComplexType on GET Method using [FromUri]

In order for swagger to allow me to call a GET with a complex type specified as my parameter, I had to do some custom modification using the OperationFilter.

Here is what the WebAPI controller action method looks like:

image

The URL should look like the following examples:

/api/blah?Id=1&secondaryid=blah
or
/api/blah?id=1&secondaryid=blah&fieldone=blah&fieldtwo=blah

Here's what happens without the operation filter:

image

Here's what I need it to do (or something similar):

image

And Here's how I got it to do that:

image

I don't want to have to do this for every single method that I have this sort of issue on. I did get this to work using that operation filter, but I already know there will be other methods similar to this same one. Is this a bug, or is there a better way to do this?

Thanks,

Alex

Broken Swagger UI with VS2013 - Web API template

I have trouble with getting Swashbuckle working with latest web-api template. I created a new WebAPI project using VS2013 ASP.Net-WebAPI template...added the Swashbuckle nuget package to it. When i navigate to \swagger\ui\index.html I get a broken Swagger UI with few elements rendered but without the API methods. The same thing with VS2012 - MVC4-WebAPI template works fine.

Am i missing any config setting? I did check everything in the troubleshoot section. Any help is appreciated.

Wrong media type for gif image

    private static string MediaTypeFor(string path)
    {
        var extension = path.Split('.').Last();

        switch (extension)
        {
            case "css":
                return "text/css";
            case "js":
                return "text/javascript";
            case "gif":
                return "image/gif";
            case "png":
                return "image/png";
            default:
                return "text/html";
        }
    }

Error handling with improperly constructed XML comments

Hi @domaindrivendev,

When the developers mess up the XML comments (like no closing tag, or using different case for closing or opening, etc), is there a way Swashbuckle can pinpoint where the XML comments are broken (instead of throwing a 500-error)? I ask this because we have hundreds of controllers already and there are going to be even more, we often encounter this problem.

Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.