本示例支持localhost和生产环境。
step1: 添加最新的包,这里是5.3.1,添加最新的即可。
- <PackageReference Include=“Swashbuckle.AspNetCore” Version=“5.3.1” />
- <PackageReference Include=“Swashbuckle.AspNetCore.Swagger” Version=“5.3.1” />
step2: 设置文件目录,这一步的目的是设置注释文件存放的目录,Debug和Release需要单独设置。我们可以在需要存放的类库对应的工程文件中(如:src/Application/Application.csproj),新增如下代码,注意下目录地址。
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\xxx.xxx.Application.xml</DocumentationFile>
<OutputPath>bin\$(Configuration)\$(TargetFramework)\</OutputPath>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\xxx.xxx.Application.xml</DocumentationFile>
<OutputPath>bin\$(Configuration)\$(TargetFramework)\</OutputPath>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
setp3: Startup.cs中注册服务,其中HttpAuthHeaderFilter是为header添加token,如果不需要的同学可以忽略。
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Wechat Doc", Version = "v1" });
c.CustomSchemaIds((type) => type.FullName);
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
var apiXmlPath = Path.Combine(basePath, "xxx.xxx.Client.xml");
var entityXmlPath = Path.Combine(basePath, "xxx.xxxx.Application.xml");
c.IncludeXmlComments(apiXmlPath);
c.IncludeXmlComments(entityXmlPath);
c.OperationFilter<HttpAuthHeaderFilter>();//这一步是为了在header中添加token验证,不需要的同学可以忽略
});
app.UseSwagger(c => { c.RouteTemplate = "swagger/{documentName}/swagger.json"; });
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint($"v1/swagger.json", "Wechat Doc V1");
});
step4: swagger默认是把属性名作为生成文档的字段名,如果我们想用JsonProperty的别名,要怎么处理呢?
- 添加包
Install the nuget package Swashbuckle.AspNetCore.Newtonsoft
- 在startup中注册
services.AddSwaggerGenNewtonsoftSupport();
step5:
访问以下两个域名即可:
域名/swagger/v1/swagger.json
域名/swagger/index.html
如果你不需要在header中添加token,到这一步就可以了。
如果需要,继续往下看二段代码
- 如果有token验证,所有打了token特性的action都在head中添加token参数
/// <summary>
/// 控制swagger中是否需要添加accesstoken验证
/// </summary>
public class HttpAuthHeaderFilter : IOperationFilter
{
/// <summary>
/// 实现接口方法
/// </summary>
/// <param name="operation"></param>
/// <param name="context"></param>
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Parameters == null)
{
operation.Parameters = new List<OpenApiParameter>();
}
if (context.ApiDescription.ActionDescriptor is ControllerActionDescriptor descriptor)
{
var actionAttributes = descriptor.MethodInfo.GetCustomAttributes(true);
bool isAuthorize = actionAttributes.Any(a => a is TokenAuthorizeAttribute);
if (isAuthorize)
{
operation.Parameters.Add(new OpenApiParameter()
{
Name = TokenAuthorizeAttribute.Token,
In = ParameterLocation.Header,
Required = true
});
}
}
}
}
- 附上token相关代码
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class TokenAuthorizeAttribute : Attribute, IFilterMetadata
{
public const string Token = "token";
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class AuthorizationFilterAttribute : Attribute, IAsyncAuthorizationFilter
{
private readonly IAuthorityApplication _authorityApplication;
public AuthorizationFilterAttribute(IAuthorityApplication authorityApplication)
{
_authorityApplication = authorityApplication ?? throw new ArgumentNullException(nameof(authorityApplication));
}
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
if (context.Filters.Any(filter => filter is TokenAuthorizeAttribute))
{
var path = context.HttpContext.Request.Path;
var token = context.HttpContext.Request.Headers[TokenAuthorizeAttribute.Token].FirstOrDefault();
var version = context.RouteData.Values["version"]?.ToString();
var plat = context.RouteData.Values["plat"]?.ToString();
if (false == await _authorityApplication.CheckPassedAsync(token, path, version, plat))
{
context.Result = new StatusCodeResult((int)HttpStatusCode.Unauthorized);
}
}
}
}
如遇到问题,欢迎留言。