Unchase Swashbuckle Asp.Net Core Extensions is a library contains a bunch of extensions (filters) for Swashbuckle.AspNetCore.
The project is developed and maintained by Nikolay Chebotov (Unchase).
Breaking Changes
- Since v2.0.0 supports Swashbuckle.AspNetCore 5.0.0 with breaking changes.
For old versions see README_OLD.md.
- Since v2.3.0 there are breaking changes in
Startup.cs
Compatibility
| Swashbuckle Version | ASP.NET Core | Swagger / OpenAPI Spec. | This extension Version |
|---|---|---|---|
| master | >= 2.0.0 | 2.0, 3.0 | master |
| 6.1.5 | >= 2.0.0 | 2.0, 3.0 | v2.6.1 |
| 6.1.0 | >= 2.0.0 | 2.0, 3.0 | v2.6.0 |
| 6.0.0 | >= 2.0.0 | 2.0, 3.0 | v2.5.1 |
| 5.0.0 | >= 2.0.0 | 2.0, 3.0 | v2.0.0 |
| 4.0.0 | >= 2.0.0, < 3.0.0 | 2.0 | v1.1.4 |
Getting Started
To use the extensions, install NuGet package into your project:
Manually with the NuGet Package Manager:
Install-Package Unchase.Swashbuckle.AspNetCore.ExtensionsUsing the .NET CLI:
dotnet add package Unchase.Swashbuckle.AspNetCore.Extensions --version {version}Where {version} is the version of the package you want to install. For example,
dotnet add package Unchase.Swashbuckle.AspNetCore.Extensions --version 2.4.0
Then use whichever extensions (filters) you need.
Extensions (Filters) use
Ensure your API actions and parameters are decorated with explicit "Http" and "From" (optional) bindings.
[HttpPost] public void CreateProduct([FromBody]Product product) ...
[HttpGet] public IEnumerable<Product> SearchProducts([FromQuery]string keywords) ...
In the Configure method, insert middleware to expose the generated Swagger as JSON endpoint(s):
Optionally, insert the swagger-ui middleware if you want to expose interactive documentation, specifying the Swagger JSON endpoint(s) to power it from:
app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); });
- Fix enums in OpenApi document:
- In the ConfigureServices method of Startup.cs, inside your
AddSwaggerGencall, enable whichever extensions (filters) you need:
using Unchase.Swashbuckle.AspNetCore.Extensions.Extensions; using Unchase.Swashbuckle.AspNetCore.Extensions.Filters;
- Since v2.3.0:
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddControllers(); // Register the Swagger generator services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); // use it if you want to hide Paths and Definitions from OpenApi documentation correctly options.UseAllOfToExtendReferenceSchemas(); // if you want to add xml comments from summary and remarks into the swagger documentation, first of all add: // you can exclude remarks for concrete types var xmlFilePath = Path.Combine(AppContext.BaseDirectory, "WebApi3.1-Swashbuckle.xml"); options.IncludeXmlCommentsWithRemarks(xmlFilePath, false, typeof(ComplicatedClass), typeof(InnerEnum)); // or add without remarks //options.IncludeXmlComments(xmlFilePath); // if you want to add xml comments from inheritdocs (from summary and remarks) into the swagger documentation, add: // you can exclude remarks for concrete types options.IncludeXmlCommentsFromInheritDocs(includeRemarks: true, excludedTypes: typeof(string)); // Add filters to fix enums // use by default: //options.AddEnumsWithValuesFixFilters(); // or configured: options.AddEnumsWithValuesFixFilters(services, o => { // add schema filter to fix enums (add 'x-enumNames' for NSwag or its alias from XEnumNamesAlias) in schema o.ApplySchemaFilter = true; // alias for replacing 'x-enumNames' in swagger document o.XEnumNamesAlias = "x-enum-varnames"; // alias for replacing 'x-enumDescriptions' in swagger document o.XEnumDescriptionsAlias = "x-enum-descriptions"; // add parameter filter to fix enums (add 'x-enumNames' for NSwag or its alias from XEnumNamesAlias) in schema parameters o.ApplyParameterFilter = true; // add document filter to fix enums displaying in swagger document o.ApplyDocumentFilter = true; // add descriptions from DescriptionAttribute or xml-comments to fix enums (add 'x-enumDescriptions' or its alias from XEnumDescriptionsAlias for schema extensions) for applied filters o.IncludeDescriptions = true; // add remarks for descriptions from xml-comments o.IncludeXEnumRemarks = true; // get descriptions from DescriptionAttribute then from xml-comments o.DescriptionSource = DescriptionSources.DescriptionAttributesThenXmlComments; // new line for enum values descriptions // o.NewLine = Environment.NewLine; o.NewLine = "\n"; // get descriptions from xml-file comments on the specified path // should use "options.IncludeXmlComments(xmlFilePath);" before o.IncludeXmlCommentsFrom(xmlFilePath); // the same for another xml-files... }); }); }
- For older versions:
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); // if you want to add xml comments into the swagger documentation, first of all add: var filePath = Path.Combine(AppContext.BaseDirectory, "WebApi3.1-Swashbuckle.xml"); options.IncludeXmlComments(filePath); // Add filters to fix enums options.AddEnumsWithValuesFixFilters(true); // or custom use: //options.SchemaFilter<XEnumNamesSchemaFilter>(true); // add schema filter to fix enums (add 'x-enumNames' for NSwag) in schema //options.ParameterFilter<XEnumNamesParameterFilter>(true); // add parameter filter to fix enums (add 'x-enumNames' for NSwag) in schema parameters //options.DocumentFilter<DisplayEnumsWithValuesDocumentFilter>(true); // add document filter to fix enums displaying in swagger document }); }
- Hide Paths and Definitions from OpenApi documentation without accepted roles:
- In the ConfigureServices method of Startup.cs, inside your
AddSwaggerGencall, enableHidePathsAndDefinitionsByRolesDocumentFilterdocument filter:
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { ... services.AddSwaggerGen(options => { ... // remove Paths and Defenitions from OpenApi documentation without accepted roles options.DocumentFilter<HidePathsAndDefinitionsByRolesDocumentFilter>(new List<string> { "AcceptedRole" }); }); }
- Since v2.2.1 you can hide Paths and Definitions from OpenApi documentation for specific controller action (or all actions) without accepted roles like this:
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { //... // enable middleware to serve generated Swagger as a JSON endpoint. app.UseSwagger(c => { c.PreSerializeFilters.Add((openApiDoc, httpRequest) => { // remove Paths and Components from OpenApi documentation for specific controller action without accepted roles openApiDoc.RemovePathsAndComponentsWithoutAcceptedRolesFor<SomeController>(controller => nameof(controller.SomeAction), new List<string> {"AcceptedRole"}); // or //openApiDoc.RemovePathsAndComponentsWithoutAcceptedRolesFor<SomeController>(nameof(SomeController.SomeAction), new List<string> { "AcceptedRole" }); // remove Paths and Components from OpenApi documentation for all controller actions without accepted roles openApiDoc.RemovePathsAndComponentsWithoutAcceptedRolesForController<AnotherController>(new List<string> {"AcceptedRole"}); // or you can get accepted roles by httpRequest like this: //openApiDoc.RemovePathsAndComponentsWithoutAcceptedRolesForController<AnotherController>(GetAcceptedRolesByRemoteIp(httpRequest.HttpContext.Connection.RemoteIpAddress)); }); }); //... }
Validated actions must be annotated with the one of HttpMethodAttribute (HttpGetAttribute, HttpPostAttribute, HttpDeleteAttribute, HttpPutAttribute, HttpPatchAttribute) attributes.
- Append action count into the SwaggetTag's descriptions in OpenApi document:
- In the ConfigureServices method of Startup.cs, inside your
AddSwaggerGencall, enableAppendActionCountToTagSummaryDocumentFilterdocument filter:
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { ... services.AddSwaggerGen(options => { ... // enable openApi Annotations options.EnableAnnotations(); // add action count (with message template) into the SwaggerTag's descriptions // you can use it after "HidePathsAndDefinitionsByRolesDocumentFilter" options.DocumentFilter<AppendActionCountToTagSummaryDocumentFilter>("(count: {0})"); ... }); }
In the controller need to use SwaggerTag attribute:
using Swashbuckle.AspNetCore.Annotations;
[SwaggerTag("Controller for todo")] public class TodoController : ControllerBase ...
- Change all responses for specific HTTP status codes in OpenApi document:
- In the ConfigureServices method of Startup.cs, inside your
AddSwaggerGencall, enableChangeAllResponsesByHttpStatusCode<T>extension (filter) with whichever HTTP status codes you need:
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { ... services.AddSwaggerGen(options => { ... // change responses for specific HTTP status code ("200") options.ChangeAllResponsesByHttpStatusCode( httpStatusCode: 200, responseDescription: "200 status code description", responseExampleOption : ResponseExampleOptions.AddNew, // add new response examples responseExample: new TodoItem { Tag = Tag.Workout, Id = 111, IsComplete = false, Name = "test" }); // some class for response examples // change responses for specific HTTP status code ("400" (HttpStatusCode.BadRequest)) options.ChangeAllResponsesByHttpStatusCode( httpStatusCode: HttpStatusCode.BadRequest, responseDescription: "400 status code description", responseExampleOption: ResponseExampleOptions.Clear, // claer response examples responseExample: new ComplicatedClass()); // some class for response examples // change responses for specific HTTP status code ("201" (StatusCodes.Status201Created)) options.ChangeAllResponsesByHttpStatusCode( httpStatusCode: StatusCodes.Status201Created, responseDescription: "201 status code description", responseExampleOption: ResponseExampleOptions.None, // do nothing with response examples responseExample: new ComplicatedClass()); // some class for response examples ... }); }
- Order tags by name in OpenApi document:
- In the ConfigureServices method of Startup.cs, inside your
AddSwaggerGencall, enableTagOrderByNameDocumentFilterdocument filter:
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { ... services.AddSwaggerGen(options => { ... // order tags by name options.DocumentFilter<TagOrderByNameDocumentFilter>(); ... }); }
- Add xml comments from summary and remarks into the swagger documentation:
- Since v2.4.0 in the ConfigureServices method of Startup.cs, inside your
AddSwaggerGencall, addIncludeXmlCommentsWithRemarksoption instead ofIncludeXmlCommentsoption:
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { ... services.AddSwaggerGen(options => { ... // add xml comments from summary and remarks into the swagger documentation options.IncludeXmlCommentsWithRemarks("<xml_File_Full_Path>"); // add xml comments from summary and remarks into the swagger documentation // with excluding remarks for concrete types (since v2.4.1) var xmlFilePath = Path.Combine(AppContext.BaseDirectory, "WebApi3.1-Swashbuckle.xml"); options.IncludeXmlCommentsWithRemarks(xmlFilePath, false, typeof(ComplicatedClass), typeof(InnerEnum)); ... }); }
- Add xml comments from <inheritdoc/> (from summary and remarks) into the swagger documentation:
- Since v2.5.0 in the ConfigureServices method of Startup.cs, inside your
AddSwaggerGencall, addIncludeXmlCommentsFromInheritDocsoption:
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { ... services.AddSwaggerGen(options => { ... // add xml comments from inheritdocs (from summary and remarks) into the swagger documentation, add: // with excluding concrete types options.IncludeXmlCommentsFromInheritDocs(includeRemarks: true, excludedTypes: typeof(string)); ... }); }
Builds status
| Status | Value |
|---|---|
| Build | |
| Tests | |
| Buid History | |
| GitHub Release | |
| GitHub Release Date | |
| GitHub Release Downloads | |
| Nuget Version | |
| Nuget Downloads |
Features
Fix enums
-
Add an output enums integer values with there strings like
0 = FirstEnumValuewithout aStringEnumConverterin swaggerUI and schema (by default enums will output only their integer values) -
Add description to each enum value that has an
[Description]attribute inswaggerUIand schema - should use options.DocumentFilter<DisplayEnumsWithValuesDocumentFilter>(true); or options.AddEnumsWithValuesFixFilters(true);In schema
parameters:In schema
definitions:To show enum values descriptions you should use
[Description]attribute in your code:/// <summary> /// Title enum. /// </summary> [DataContract] public enum Title { /// <summary> /// None. /// </summary> [Description("None enum description")] [EnumMember] None = 0, /// <summary> /// Miss. /// </summary> [Description("Miss enum description")] [EnumMember] Miss, /// <summary> /// Mr. /// </summary> [Description("Mr enum description")] [EnumMember] Mr } ... /// <summary> /// Sample Person request and response. /// </summary> public class SamplePersonRequestResponse { /// <summary> /// Sample Person title. /// </summary> public Title Title { get; set; } /// <summary> /// Sample Person age. /// </summary> public int Age { get; set; } /// <summary> /// Sample Person firstname. /// </summary> [Description("The first name of the person")] public string FirstName { get; set; } /// <summary> /// Sample Person income. /// </summary> public decimal? Income { get; set; } }
-
Fix enum values in generated by
NSwagStudioor Unchase OpenAPI Connected Service client classes:/// <summary>Sample Person title. /// /// 0 = None (None enum description) /// /// 1 = Miss (Miss enum description) /// /// 2 = Mr (Mr enum description)</summary> [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "9.13.35.0 (Newtonsoft.Json v11.0.0.0)")] public enum Title { None = 0, Miss = 1, Mr = 2, }
Hide Paths and Defenitions from OpenApi documentation
-
Hide all OpenAPIDocument Paths and Defenitions without accepted roles:
You should use
AuthorizeAttributefor methods or controllers:... public class SamplePersonController : ControllerBase { // this method will not be hidden with using 'swaggerDoc.HidePathItemsWithoutAcceptedRoles(new List<string> {"AcceptedRole"});' [Authorize(Roles = "AcceptedRole")] [HttpGet] public ActionResult<SamplePersonRequestResponse> Get(Title title) { ... } // this method will be hidden with using 'swaggerDoc.HidePathItemsWithoutAcceptedRoles(new List<string> {"AcceptedRole"});' [Authorize(Roles = "NotAcceptedRole")] [HttpPost] public ActionResult<SamplePersonRequestResponse> Post([FromBody] SamplePersonRequestResponse request) { ... } }
Append action count into the SwaggetTag's descriptions
You should use SwaggerTagAttribute for controllers:
[SwaggerTag("SamplePerson description")] public class SamplePersonController : ControllerBase { ... }
Change responses for specific HTTP status codes
For example:
Add xml comments from summary and remarks into the swagger documentation
For code:
/// <summary> /// Inner class /// </summary> /// <remarks> /// Inner class remarks - class /// </remarks> public class InnerClass { /// <summary> /// List of inner enums /// </summary> /// <remarks> /// List of inner enums remarks - property /// </remarks> public List<InnerEnum> InnerEnum { get; set; } /// <summary> /// Second inner class /// </summary> /// <remarks> /// Second inner class remarks - property /// </remarks> public SecondInnerClass<SecondInnerEnum> SecondInnerClass { get; set; } } /// <summary> /// Inner enum /// </summary> /// <remarks> /// Inner enum remarks - enum /// </remarks> public enum InnerEnum { /// <summary> /// Inner enum value /// </summary> /// <remarks> /// Inner enum value remarks /// </remarks> Value = 1 } /// <summary> /// Second inner class /// </summary> /// <remarks> /// Second inner class remarks - class /// </remarks> public class SecondInnerClass<T> where T : Enum { /// <summary> /// Second inner enum /// </summary> /// <remarks> /// Second inner enum remarks - property /// </remarks> public T InnerEnum { get; set; } } /// <summary> /// Second inner enum /// </summary> /// <remarks> /// Second inner enum remarks - enum /// </remarks> public enum SecondInnerEnum { /// <summary> /// Second inner enum value /// </summary> /// <remarks> /// Second inner enum value remarks /// </remarks> Value = 0 }
Add xml comments from <inheritdoc/> (from summary and remarks) into the swagger documentation
For code:
/// <inheritdoc cref="IInheritDocClass"/> public class InheritDocClass : IInheritDocClass { /// <inheritdoc/> public string Name { get; set; } /// <inheritdoc/> public string Common { get; set; } /// <inheritdoc/> public InheritEnum InheritEnum { get; set; } } /// <summary> /// InheritDocClass - inheritdoc /// </summary> /// <remarks> /// InheritDocClass remarks - inheritdoc /// </remarks> public interface IInheritDocClass : IInheritDocCommon { /// <summary> /// Name - inheritdoc /// </summary> /// <remarks> /// Name remarks - inheritdoc /// </remarks> public string Name { get; set; } } /// <summary> /// IInheritDocCommon interface /// </summary> /// <remarks> /// IInheritDocCommon interface remarks /// </remarks> public interface IInheritDocCommon { /// <summary> /// Common - inheritdoc (inner) /// </summary> /// <remarks> /// Common remarks - inheritdoc (inner) /// </remarks> public string Common { get; set; } /// <summary> /// InheritEnum - inheritdoc (inner) /// </summary> public InheritEnum InheritEnum { get; set; } } /// <summary> /// Inherit enum - enum /// </summary> /// <remarks> /// Inherit enum remarks - enum /// </remarks> public enum InheritEnum { /// <summary> /// Inherit enum Value /// </summary> /// <remarks> /// Inherit enum Value remarks /// </remarks> Value = 0 }
HowTos
- Add HowTos in a future
- ... request for HowTo you need
Roadmap
See the changelog for the further development plans and version history.
Feedback
Please feel free to add your request a feature or report a bug. Thank you in advance!
Thank me!
If you like what I am doing and you would like to thank me, please consider:
Thank you for your support!
Copyright © 2019 Nikolay Chebotov (Unchase) - Provided under the Apache License 2.0.








