Intro
上次更新了 ASP.NET core 3.0 简单的记录了一下 swagger 的使用, 那个项目的 API 比较简单, 都是匿名接口不涉及到认证以及 API 版本控制, 最近把另外一个 API 项目升级到了 3.0, 还是遇到了一些问题, 这里单独写一篇文章介绍, 避免踩坑.
Swagger 基本使用
swagger 服务注册:
- services.AddSwaggerGen(option =>
- {
- option.SwaggerDoc("sparktodo", new OpenApiInfo
- {
- Version = "v1",
- Title = "SparkTodo API",
- Description = "API for SparkTodo",
- Contact = new OpenApiContact() { Name = "WeihanLi", Email = "weihanli@outlook.com" }
- });
- // include document file
- option.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{typeof(Startup).Assembly.GetName().Name}.xml"), true);
- });
中间件配置:
- //Enable middleware to serve generated Swagger as a JSON endpoint.
- App.UseSwagger();
- //Enable middleware to serve swagger-ui (html, JS, CSS etc.), specifying the Swagger JSON endpoint
- App.UseSwaggerUI(option =>
- {
- option.SwaggerEndpoint("/swagger/sparktodo/swagger.json", "sparktodo Docs");
- option.RoutePrefix = string.Empty;
- option.DocumentTitle = "SparkTodo API";
- });
为 Swagger 添加 Bearer Token 认证
- services.AddSwaggerGen(option =>
- {
- // ...
- // Add security definitions
- option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
- {
- Description = "Please enter into field the word'Bearer'followed by a space and the JWT value",
- Name = "Authorization",
- In = ParameterLocation.Header,
- Type = SecuritySchemeType.ApiKey,
- });
- option.AddSecurityRequirement(new OpenApiSecurityRequirement
- {
- { new OpenApiSecurityScheme
- {
- Reference = new OpenApiReference()
- {
- Id = "Bearer",
- Type = ReferenceType.SecurityScheme
- }
- }, Array.Empty<string>() }
- });
- });
支持多个 ApiVersion
- services.AddApiVersioning(options =>
- {
- options.AssumeDefaultVersionWhenUnspecified = true;
- options.DefaultApiVersion = ApiVersion.Default;
- options.ReportApiVersions = true;
- });
- services.AddSwaggerGen(option =>
- {
- // ...
- option.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "API V1" });
- option.SwaggerDoc("v2", new OpenApiInfo { Version = "v2", Title = "API V2" });
- option.DocInclusionPredicate((docName, apiDesc) =>
- {
- var versions = apiDesc.CustomAttributes()
- .OfType<ApiVersionAttribute>()
- .SelectMany(attr => attr.Versions);
- return versions.Any(v => $"v{v.ToString()}" == docName);
- });
- option.OperationFilter<RemoveVersionParameterOperationFilter>();
- option.DocumentFilter<SetVersionInPathDocumentFilter>();
- });
自定义 API version 相关的 OperationFilter:
- public class SetVersionInPathDocumentFilter : IDocumentFilter
- {
- public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
- {
- var updatedPaths = new OpenApiPaths();
- foreach (var entry in swaggerDoc.Paths)
- {
- updatedPaths.Add(
- entry.Key.Replace("v{version}", swaggerDoc.Info.Version),
- entry.Value);
- }
- swaggerDoc.Paths = updatedPaths;
- }
- }
- public class RemoveVersionParameterOperationFilter : IOperationFilter
- {
- public void Apply(OpenApiOperation operation, OperationFilterContext context)
- {
- // Remove version parameter from all Operations
- var versionParameter = operation.Parameters.Single(p => p.Name == "version");
- operation.Parameters.Remove(versionParameter);
- }
- }
中间件配置:
- //Enable middleware to serve generated Swagger as a JSON endpoint.
- App.UseSwagger();
- //Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint
- App.UseSwaggerUI(option =>
- {
- option.SwaggerEndpoint("/swagger/v2/swagger.json", "V2 Docs");
- option.SwaggerEndpoint("/swagger/v1/swagger.json", "V1 Docs");
- option.RoutePrefix = string.Empty;
- option.DocumentTitle = "SparkTodo API";
- });
最终 swagger 效果
Memo
上面的配置来自 https://github.com/WeihanLi/SparkTodo 这个项目, 要获取代码可以参考这个项目
- Reference
- https://github.com/WeihanLi/SparkTodo
来源: https://www.cnblogs.com/weihanli/p/ues-swagger-in-aspnetcore3_0.html