.net core swagger配置

烂柯 发布于 2022-05-24 326 次阅读


一、概述

​ 记录asp.net core使用swagger及修改swagger枚举类描述信息。

Swashbuckle 有三个主要组件

  • Swashbuckle 有三个主要组件:

    Swashbuckle.AspNetCore.Swagger:将 SwaggerDocument 对象公开为 JSON 终结点的 Swagger 对象模型和中间件。

    Swashbuckle.AspNetCore.SwaggerGen:从路由、控制器和模型直接生成 SwaggerDocument 对象的 Swagger 生成器。 它通常与 Swagger 终结点中间件结合,以自动公开 Swagger JSON。

    Swashbuckle.AspNetCore.SwaggerUI:Swagger UI 工具的嵌入式版本。 它解释 Swagger JSON 以构建描述 Web API 功能的可自定义的丰富体验。 它包括针对公共方法的内置测试工具。

二、引用

安装包: Swashbuckle.AspNetCore

Install-Package Swashbuckle.AspNetCore

三、基础配置

1、添加Swagger服务

if (builder.Environment.IsDevelopment())
{
    builder.Services.AddSwaggerGen(option=>
    {
        //1.添加文档描述
        option.SwaggerDoc("v1", new OpenApiInfo { Title = "Api", Version = "v1" });
        //2.启用添加token验证输入
        option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
        {
            Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入{Authorization}\"",
            Name = "Authorization",//jwt默认的参数名称
            In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)
            Type = SecuritySchemeType.ApiKey
        });
        option.AddSecurityRequirement(new OpenApiSecurityRequirement {{new OpenApiSecurityScheme
        {
            Reference=new OpenApiReference()
            {
                Id="Bearer",
                Type=ReferenceType.SecurityScheme
            }
        },Array.Empty<string>() }});
        //3.添加xml文档描述(右键项目属性>生成>输出>勾选文档文件)
        var docXml = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.xml");
        foreach (var doc in docXml)
        {
            options.IncludeXmlComments(doc, Path.GetFileNameWithoutExtension(doc)==AppDomain.CurrentDomain.FriendlyName);
        }
    });
}

2、添加swagger中间件

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    //app.UseSwaggerUI();
    //添加多个swagger端点
    app.UseSwaggerUI(option =>
    {
        option.SwaggerEndpoint("/swagger/v1/swagger.json", "api service");
        //swagger访问路由,为空时直接访问
        option.RoutePrefix=string.Empty;
    });
}

四、设置枚举

1、配置枚举类型

枚举默认为int类型,展示也是展示的int数组,改为字符串可以按照下列方式调整。

使用框架自带的Json序列化

builder.Services.AddControllers().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});

使用NewtonsoftJson序列化

builder.Services.AddControllers().AddNewtonsoftJson(options =>
{
    options.SerializerSettings.Converters.Add(new StringEnumConverter()));
}
//services.AddSwaggerGenNewtonsoftSupport();

2、修改描述信息

通过过滤器方式修改

public class XmlEnumSchemaFilter : ISchemaFilter
{
    private readonly XPathNavigator _xmlNavigator;
    public XmlEnumSchemaFilter(string xmlDocPath)
    {
        _xmlNavigator = new XPathDocument(xmlDocPath).CreateNavigator();
    }
    public void Apply(OpenApiSchema model, SchemaFilterContext context)
    {
        if (!context.Type.IsEnum)
            return;
        string? typeMemberName = XmlCommentsNodeNameHelper.GetMemberNameForType(context.Type);
        if (typeMemberName == null)
            return;
        XPathNavigator? typeSummaryNode = _xmlNavigator.SelectSingleNode($"/doc/members/member[@name='{typeMemberName}']/summary");
        if (typeSummaryNode == null)
            return;
        //描述信息
        StringBuilder description = new StringBuilder(model.Description);
        description.Append(":     ");
        FieldInfo[] enumItems = context.Type.GetFields(BindingFlags.Static | BindingFlags.Public);
        foreach (FieldInfo field in enumItems)
        {
            string enumString = $"{Convert.ToInt64(Enum.Parse(context.Type, field.Name))}={field.Name}";
            string? fieldOrPropertyMemberName = XmlCommentsNodeNameHelper.GetMemberNameForFieldOrProperty(field);
            if (fieldOrPropertyMemberName == null)
                continue;
            XPathNavigator? fieldOrPropertyNode = _xmlNavigator.SelectSingleNode($"/doc/members/member[@name='{fieldOrPropertyMemberName}']");
            if (fieldOrPropertyNode == null)
                continue;
            var summaryNode = fieldOrPropertyNode.SelectSingleNode("summary");
            if (summaryNode == null)
                continue;
            string fieldDescription = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml);
            description.Append(enumString);
            description.Append("(");
            description.Append(fieldDescription);
            description.Append(")、");
        }

        model.Description = description.ToString().TrimEnd('、');
    }
}

配置过滤器

builder.Services.AddSwaggerGen(options =>
{
    //...
    var docXml = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.xml");
    foreach (var doc in docXml)
    {
        options.IncludeXmlComments(doc, Path.GetFileNameWithoutExtension(doc)==AppDomain.CurrentDomain.FriendlyName);
        //必须在IncludeXmlComments之后
        options.SchemaFilter<XmlEnumSchemaFilter>(doc);
    }
});
烂柯