asp.net core 3.0 中使用 swagger
Intro
上次更新了 asp.net core 3.0 简单的记录了一下 swagger 的使用,详细可以参考asp.net core3.0更新简记,那个项目的 api 比较简单,都是匿名接口不涉及到认证以及 api 版本控制,最近把另外一个 api 项目升级到了 3.0,还是遇到了一些问题,这里单独写一篇文章介绍,避免踩坑。
Swagger 基本使用
安装 nuget 包 Swashbuckle.AspNetCore ,需要使用 5.0.x 版本,使用最新的 5.0.0-rc 版本(还没发稳定版,需要显示预览版本才能看到)
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,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/domaindrivendev/Swashbuckle.AspNetCore/tree/master/test/WebSites/MultipleVersions/Swagger
- https://stackoverflow.com/questions/58197244/swaggerui-with-netcore-3-0-bearer-token-authorization
- https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1295
- https://github.com/WeihanLi/SparkTodo
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|