Custom swagger document filter
This code sample shows how to set up and construct a document swagger filter, as well as how to establish a service extension.
First, create a simple class for holding the default swagger information.
public class SwaggerSettingsModel{ public string EndPointUrl { get; set; } public string Title { get; set; } public string Version { get; set; } public string Description { get; set; } public string TermsOfService { get; set; } public string ContactName { get; set; } public string ContactEmail { get; set; } public string ContactUrl { get; set; } public bool FilterByCertAuth { get; set; }}
After that, create a new file for the Extension, something like: CustomSwaggerServiceCollectionExtension.cs
public static class CustomSwaggerGenServiceCollectionExtensions{ public static IServiceCollection AddCustomSwaggerGen( this IServiceCollection services, SwaggerSettingsModel settings, string customDescription) { Action<SwaggerGenOptions> options = genOptions => { genOptions.SwaggerDoc(settings.Version, new Info { Title = settings.Title, Version = settings.Version, Description = !string.IsNullOrEmpty(customDescription) ? customDescription : settings.Description, TermsOfService = settings.TermsOfService, Contact = new Contact { Name = settings.ContactName, Email = settings.ContactEmail, Url = settings.ContactUrl } });
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
genOptions.IncludeXmlComments(xmlPath); genOptions.DocumentFilter<EnumDocumentFilter>(); genOptions.DocumentFilter<UserAuthorisationDocumentFilter>(settings); genOptions.SchemaFilter<CertSchemaFilter>(); }; return services.AddSwaggerGen(options); }}
A lot of things are happening in this Swagger Extension. SwaggerGenOptions will use the enclosed model above to read the XML-supplied information in the XML as comments.
The DocumentFilter is the most intriguing feature. They come in helpful when you need to change any portion of the produced document. I've included an EnumDocumentFilter here. The purpose of this filter is to display values for enum names.
CertSchemaFillter is a document filter based on the user's client certificate. Certificate properties, for example, may then be used to filter the document. Credentials are mainly in the form of a username and password. If you want the username and password properties deleted for each API request and utilize client certificates, this filter may come in useful.
public class CertSchemaFilter : ISchemaFilter{ private readonly IHttpContextAccessor _httpContextAccessor;
public CertSchemaFilter(IHttpContextAccessor httpContextAccessor) { this._httpContextAccessor = httpContextAccessor; }
public void Apply(Schema schema, SchemaFilterContext context) { if (this._httpContextAccessor.HttpContext.Connection.ClientCertificate != null) { var typeInfo = context.SystemType.GetTypeInfo();
if (typeInfo.BaseType == typeof(CredentialsModel)) { schema.Properties.Remove(nameof(CredentialsModel.Username).ToLower()); schema.Properties.Remove(nameof(CredentialsModel.Password).ToLower()); } } }}
Don't forget to register this extension in the startup.cs In the ConfigureService method, add:
services.AddCustomSwaggerGen(SwaggerSettings, this.CreateSwaggerDescription());
Maybe I will add more DocumentFilter examples when I have some spare time.