Middlewares

Rico Suter edited this page Jul 2, 2018 · 40 revisions
  • Package: NSwag.AspNet.Owin (.NET 4.5+)
  • Package: NSwag.AspNetCore (.NETStandard 1.6+, .NET Core and .NET 4.5.1+)

Both NuGet packages provide extension methods to register OWIN or ASP.NET Core middlewares:

Swagger only:

  • app.UseSwagger(assembly, configure): Registers the Swagger generator on a given route

Swagger and Swagger UI:

  • app.UseSwaggerUi(assembly, configure): Registers the Swagger generator and Swagger UI v2.x on the given routes
  • app.UseSwaggerUi(configure): Registers only the Swagger UI on the given route
  • app.UseSwaggerUi3(configure): Registers the Swagger generator and Swagger UI v3.x on the given routes
  • app.UseSwaggerReDoc(configure): Registers the Swagger generator and ReDoc on the given routes

Using new ASP.NET Core generator based on API Explorer:

  • app.UseSwagggerWithApiExplorer(configure) (Swagger only)
  • app.UseSwaggger*WithApiExplorer(configure) (Swagger and Swagger UI): New generators which use the ASP.NET Core API Explorer

The default routes to access the Swagger specification or Swagger UI:

  • Swagger JSON: http://yourserver/swagger/v1/swagger.json
  • Swagger UI: http://yourserver/swagger

Sample project

Integration

See also:

1. Install required NuGet packages

First, you need to install the required NSwag NuGet packages.

OWIN ASP.NET Middleware: Full .NET 4.5+ Framework:

ASP.NET Core Middleware: .NETStandard 1.6+, .NET Core and .NET 4.5.1+:

2. Register the middleware

ASP.NET Core

public class Startup
{
    ...

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSwagger(); // only needed for the UseSwaggger*WithApiExplorer() methods (below)
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseMvc();
        
        // Either use the reflection based generator for ASP.NET or ASP.NET Core:
        app.UseSwaggerUi(typeof(Startup).GetTypeInfo().Assembly, settings =>
        {
            ...

        // or use the new API Explorer based generator (ASP.NET Core only)
        app.UseSwaggerUiWithApiExplorer(settings =>
        {
            ...

ASP.NET OWIN

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();

        app.UseSwaggerUi(typeof(Startup).Assembly, settings => 
        {
            // configure settings here
            // settings.GeneratorSettings.*: Generator settings and extension points
            // settings.*: Routing and UI settings
        });
        app.UseWebApi(config);

        config.MapHttpAttributeRoutes();
        config.EnsureInitialized();
    }
}

Register only the Swagger generator (in this example: OWIN .NET 4.5+):

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();

        app.UseSwagger(typeof(Startup).Assembly, settings => 
        {
            // configure settings here
        });
        app.UseWebApi(config);

        config.MapHttpAttributeRoutes();
        config.EnsureInitialized();
    }
}

Configure the routing of the Swagger requests

There are two ways to do this:

a) Pipe all request to the .NET pipeline

In the system.webServer tag, set runAllManagedModulesForAllRequests to true so that all requests are piped to ASP.NET:

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

b) Pipe only the Swagger request to the specific middlewares

Important: The routes defined in the web.config and the UseSwagger/UseSwaggerUi methods must be the same:

<system.webServer>
    ...
    <handlers>
        ...
        <add name="NSwag" path="swagger" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

Customization

Usage with a custom default URL template

When you are using the Web API to Swagger generator in an MVC web application, you may have to change the URL template to the one defined in the Startup.cs:

app.UseSwaggerUi(typeof(Startup).GetTypeInfo().Assembly, settings => 
{
    settings.GeneratorSettings.DefaultUrlTemplate = "{controller}/{action}/{id?}";
});

Post process the served Swagger specification

It is possible to transform the generated Swagger specification before it is served to the client:

app.UseSwagger(typeof(Startup).Assembly, settings =>
{
    settings.PostProcess = document => 
    {
        document.Info.Description = "My description"; 
    };
});

If you want to implement more reusable code, you can also implement Document Processors and Operation Processors.

Generate multiple Swagger specifications

https://github.com/RSuter/NSwag/issues/1393#issuecomment-401747882

Enable authorization in generator and Swagger UI

Enable OAuth2 authorization

app.UseSwaggerUi(typeof(Startup).Assembly, settings => 
{
    settings.OAuth2Client = new OAuth2ClientSettings
    {
        ClientId = "foo",
        ClientSecret = "bar",
        AppName = "my_app",
        Realm = "my_realm",
        AdditionalQueryStringParameters =
        {
            { "foo", "bar" }
        }
    };

    settings.GeneratorSettings.DocumentProcessors.Add(new SecurityDefinitionAppender("oauth2", new SwaggerSecurityScheme
    {
        Type = SwaggerSecuritySchemeType.OAuth2,
        Description = "Foo",
        Flow = SwaggerOAuth2Flow.Implicit,
        AuthorizationUrl = "https://localhost:44333/core/connect/authorize",
        TokenUrl = "https://localhost:44333/core/connect/token",
        Scopes = new Dictionary<string,string>
        {
            { "read", "Read access to protected resources" },
            { "write", "Write access to protected resources" }
        }
    }));

    settings.GeneratorSettings.OperationProcessors.Add(new OperationSecurityScopeProcessor("oauth2"));
});

Enable API Key authorization

app.UseSwaggerUi(typeof(Startup).Assembly, settings => 
{
    settings.GeneratorSettings.DocumentProcessors.Add(new SecurityDefinitionAppender("apikey", new SwaggerSecurityScheme
    {
        Type = SwaggerSecuritySchemeType.ApiKey,
        Name = "api_key",
        In = SwaggerSecurityApiKeyLocation.Header
    });
});

Hack: Ask user for client ID and client secret

To let the user enter the client ID and client secret, use the following code for now:

new OAuth2ClientSettings
{
    ClientId = "\" + prompt('Please enter ClientId: ') + \"",
    ClientSecret = "\" + prompt('Please enter ClientSecret: ') + \""
}