NSwag provides comprehensive ASP.NET Core integration through middleware and services that automatically generate and serve OpenAPI specifications with optional Swagger UI interfaces. This integration enables seamless API documentation and client generation workflows.
Extension methods for registering NSwag services in the dependency injection container.
public static class NSwagServiceCollectionExtensions
{
public static IServiceCollection AddOpenApiDocument(this IServiceCollection services);
public static IServiceCollection AddOpenApiDocument(this IServiceCollection services, Action<AspNetCoreOpenApiDocumentGeneratorSettings> configure);
public static IServiceCollection AddSwaggerDocument(this IServiceCollection services);
public static IServiceCollection AddSwaggerDocument(this IServiceCollection services, Action<AspNetCoreOpenApiDocumentGeneratorSettings> configure);
public static IServiceCollection ConfigureOpenApiDocument(this IServiceCollection services, Action<AspNetCoreOpenApiDocumentGeneratorSettings> configure);
public static IServiceCollection ConfigureSwaggerDocument(this IServiceCollection services, Action<AspNetCoreOpenApiDocumentGeneratorSettings> configure);
}Extension methods for registering NSwag middleware in the request pipeline.
public static class NSwagApplicationBuilderExtensions
{
public static IApplicationBuilder UseOpenApi(this IApplicationBuilder app);
public static IApplicationBuilder UseOpenApi(this IApplicationBuilder app, Action<OpenApiDocumentMiddlewareSettings> configure);
public static IApplicationBuilder UseSwaggerUi3(this IApplicationBuilder app);
public static IApplicationBuilder UseSwaggerUi3(this IApplicationBuilder app, Action<SwaggerUi3Settings> configure);
public static IApplicationBuilder UseSwaggerUi(this IApplicationBuilder app);
public static IApplicationBuilder UseSwaggerUi(this IApplicationBuilder app, Action<SwaggerUiSettings> configure);
public static IApplicationBuilder UseReDoc(this IApplicationBuilder app);
public static IApplicationBuilder UseReDoc(this IApplicationBuilder app, Action<ReDocSettings> configure);
}// Program.cs or Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddOpenApiDocument(); // Register OpenAPI document generation
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
// Register the OpenAPI specification middleware
app.UseOpenApi();
// Register the Swagger UI middleware
app.UseSwaggerUi3();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddOpenApiDocument(config =>
{
config.Title = "My Web API";
config.Version = "v1";
config.Description = "ASP.NET Core Web API with OpenAPI documentation";
// Add JWT authentication
config.AddSecurity("JWT", Enumerable.Empty<string>(), new OpenApiSecurityScheme
{
Type = OpenApiSecuritySchemeType.ApiKey,
Name = "Authorization",
In = OpenApiSecurityApiKeyLocation.Header,
Description = "Type into the textbox: Bearer {your JWT token}."
});
config.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("JWT"));
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseOpenApi(settings =>
{
settings.Path = "/swagger/v1/swagger.json";
settings.PostProcess = (document, request) =>
{
document.Info.Version = "v1.0";
};
});
app.UseSwaggerUi3(settings =>
{
settings.Path = "/swagger";
settings.DocumentPath = "/swagger/v1/swagger.json";
settings.DocExpansion = "list";
});
}Serves the OpenAPI specification document.
public class OpenApiDocumentMiddleware
{
public OpenApiDocumentMiddleware(RequestDelegate next, IDocumentProvider documentProvider, OpenApiDocumentMiddlewareSettings settings);
public Task InvokeAsync(HttpContext context);
}Configuration for the OpenAPI document middleware.
public class OpenApiDocumentMiddlewareSettings
{
public string Path { get; set; } = "/swagger/v1/swagger.json";
public string DocumentName { get; set; } = "v1";
public Action<OpenApiDocument, HttpRequest> PostProcess { get; set; }
public Func<HttpRequest, bool> CreateDocumentIfNotExist { get; set; }
}Configuration for Swagger UI 3.
public class SwaggerUi3Settings : SwaggerUiSettingsBase<SwaggerUi3Settings>
{
// OAuth2 configuration
public OAuth2ClientSettings OAuth2Client { get; set; }
public bool PersistAuthorization { get; set; }
// Display options
public bool DisplayOperationId { get; set; }
public string DefaultModelsExpandDepth { get; set; }
public string DefaultModelExpandDepth { get; set; }
public string DefaultModelRendering { get; set; }
public bool DisplayRequestDuration { get; set; }
public string DocExpansion { get; set; }
public string Filter { get; set; }
public int MaxDisplayedTags { get; set; }
public bool ShowExtensions { get; set; }
public bool ShowCommonExtensions { get; set; }
// Request options
public bool UseUnsafeInline { get; set; }
public IDictionary<string, object> AdditionalSettings { get; set; }
}Configuration for Swagger UI 2 (legacy).
public class SwaggerUiSettings : SwaggerUiSettingsBase<SwaggerUiSettings>
{
public bool EnableValidator { get; set; }
public string ValidatorUrl { get; set; }
public IDictionary<string, object> AdditionalSettings { get; set; }
}Base class for Swagger UI settings.
public abstract class SwaggerUiSettingsBase<T> where T : SwaggerUiSettingsBase<T>
{
public string Path { get; set; } = "/swagger";
public string DocumentPath { get; set; } = "/swagger/v1/swagger.json";
public string DocumentTitle { get; set; } = "Swagger UI";
// Customization
public string CustomStylesheetPath { get; set; }
public string CustomJavaScriptPath { get; set; }
public string CustomHeadContent { get; set; }
public string FaviconPath { get; set; }
// Server settings
public Func<HttpRequest, string> TransformToExternalPath { get; set; }
public string ServerUrl { get; set; }
// OAuth settings
public string OAuth2RedirectPath { get; set; }
}Configuration for ReDoc documentation UI.
public class ReDocSettings
{
public string Path { get; set; } = "/redoc";
public string DocumentPath { get; set; } = "/swagger/v1/swagger.json";
public string DocumentTitle { get; set; } = "ReDoc";
// ReDoc-specific options
public string ScrollYOffset { get; set; }
public bool HideDownloadButton { get; set; }
public bool HideHostname { get; set; }
public bool ExpandResponses { get; set; }
public bool RequiredPropsFirst { get; set; }
public bool NoAutoAuth { get; set; }
public bool PathInMiddlePanel { get; set; }
public bool HideLoading { get; set; }
public bool NativeScrollbars { get; set; }
public string Theme { get; set; }
// Customization
public string CustomStylesheetPath { get; set; }
public string CustomJavaScriptPath { get; set; }
public string CustomHeadContent { get; set; }
public string FaviconPath { get; set; }
// Server settings
public Func<HttpRequest, string> TransformToExternalPath { get; set; }
public string ServerUrl { get; set; }
public IDictionary<string, object> AdditionalSettings { get; set; }
}Interface for providing OpenAPI documents.
public interface IDocumentProvider
{
Task<OpenApiDocument> GetDocumentAsync(string documentName, string host);
void InvalidateDocument(string documentName);
}Default implementation of the document provider.
public class OpenApiDocumentProvider : IDocumentProvider
{
public OpenApiDocumentProvider(IServiceProvider serviceProvider);
public Task<OpenApiDocument> GetDocumentAsync(string documentName, string host);
public void InvalidateDocument(string documentName);
}public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
// Register multiple API versions
services.AddOpenApiDocument(config =>
{
config.DocumentName = "v1";
config.Title = "My API v1";
config.Version = "1.0";
config.ApiGroupNames = new[] { "v1" };
});
services.AddOpenApiDocument(config =>
{
config.DocumentName = "v2";
config.Title = "My API v2";
config.Version = "2.0";
config.ApiGroupNames = new[] { "v2" };
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Serve multiple documents
app.UseOpenApi();
// Multiple Swagger UIs
app.UseSwaggerUi3(settings =>
{
settings.SwaggerRoutes.Add(new SwaggerUiRoute("v1", "/swagger/v1/swagger.json"));
settings.SwaggerRoutes.Add(new SwaggerUiRoute("v2", "/swagger/v2/swagger.json"));
});
}services.AddOpenApiDocument(config =>
{
config.AddSecurity("JWT", Enumerable.Empty<string>(), new OpenApiSecurityScheme
{
Type = OpenApiSecuritySchemeType.Http,
Name = "JWT",
Scheme = "bearer",
BearerFormat = "JWT",
Description = "Specify the authorization token."
});
config.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("JWT"));
});services.AddOpenApiDocument(config =>
{
config.AddSecurity("ApiKey", Enumerable.Empty<string>(), new OpenApiSecurityScheme
{
Type = OpenApiSecuritySchemeType.ApiKey,
Name = "X-API-Key",
In = OpenApiSecurityApiKeyLocation.Header,
Description = "API Key Authentication"
});
config.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("ApiKey"));
});services.AddOpenApiDocument(config =>
{
config.AddSecurity("OAuth2", Enumerable.Empty<string>(), new OpenApiSecurityScheme
{
Type = OpenApiSecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = "https://auth.example.com/oauth/authorize",
TokenUrl = "https://auth.example.com/oauth/token",
Scopes = new Dictionary<string, string>
{
{ "read", "Read access" },
{ "write", "Write access" }
}
}
}
});
});
// Configure Swagger UI OAuth2
app.UseSwaggerUi3(settings =>
{
settings.OAuth2Client = new OAuth2ClientSettings
{
ClientId = "swagger-ui",
AppName = "Swagger UI"
};
});services.AddOpenApiDocument(config =>
{
config.PostProcess = document =>
{
document.Info.Title = "Custom Processed API";
document.Info.Contact = new OpenApiContact
{
Name = "API Support",
Email = "support@example.com",
Url = "https://example.com/support"
};
};
});public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseOpenApi();
app.UseSwaggerUi3();
}
else if (env.IsStaging())
{
app.UseOpenApi(settings =>
{
settings.PostProcess = (doc, req) =>
{
doc.Host = "staging-api.example.com";
};
});
app.UseSwaggerUi3();
}
// Production: No Swagger UI, only OpenAPI spec
else
{
app.UseOpenApi();
}
}app.UseSwaggerUi3(settings =>
{
settings.Path = "/api-docs";
settings.DocumentPath = "/api-docs/openapi.json";
settings.DocumentTitle = "My Company API Documentation";
settings.CustomStylesheetPath = "/swagger-ui/custom.css";
settings.CustomJavaScriptPath = "/swagger-ui/custom.js";
settings.FaviconPath = "/favicon.ico";
// Custom head content
settings.CustomHeadContent = "<style>body { font-family: 'Arial', sans-serif; }</style>";
// Transform external paths for reverse proxy scenarios
settings.TransformToExternalPath = (internalUiRoute, request) =>
{
return "/external" + internalUiRoute;
};
});services.AddApiVersioning(setup =>
{
setup.DefaultApiVersion = new ApiVersion(1, 0);
setup.AssumeDefaultVersionWhenUnspecified = true;
setup.VersionReader = ApiVersionReader.Combine(
new HeaderApiVersionReader("X-Version"),
new QueryStringApiVersionReader("version")
);
});
services.AddVersionedApiExplorer(setup =>
{
setup.GroupNameFormat = "'v'VVV";
setup.SubstituteApiVersionInUrl = true;
});
// Generate documents for each version
services.AddOpenApiDocument((config, serviceProvider) =>
{
var versionDescriptionProvider = serviceProvider.GetRequiredService<IApiVersionDescriptionProvider>();
foreach (var description in versionDescriptionProvider.ApiVersionDescriptions)
{
config.DocumentName = description.GroupName;
config.ApiGroupNames = new[] { description.GroupName };
config.Title = $"My API {description.ApiVersion}";
config.Version = description.ApiVersion.ToString();
}
});