首页 > 解决方案 > Swashbuckle SchemaFilter 用于 api 操作参数

问题描述

我已成功创建ISchemaFilter以扩展swagger.json枚举属性定义以用于代码生成目的,如此所述。这是我目前的SchemaFilter.Apply方法:

public void Apply(Schema schema, SchemaFilterContext context)
{
    if (context.SystemType.IsEnum)
    {
        var names = Enum.GetNames(context.SystemType);
        var values = Enum.GetValues(context.SystemType);
        var desc = "";

        foreach (var value in values)
        {
            var intValue = Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType()));
            desc += $"{intValue}={value},";
        }
        desc = desc.TrimEnd(',');
        schema.Extensions.Add("x-enumNames", names);
        schema.Extensions["description"] = desc;
    }
}

SchemaFilter在我的模型定义上正常工作,其中模型类具有枚举类型的成员。以下是输出示例:resolution-field,它是枚举类型,注意自定义x-enumNames和修改description字段:

resolution: {
    format: "int32",
    enum: [
        1,
        2,
        3,
        4
    ],
    type: "integer",
    x-enumNames: [
        "Hour",
        "Day",
        "Month",
        "Year"
    ],
    description: "1=Hour,2=Day,3=Month,4=Year"
}

问题是它SchemaFilter不扩展操作参数中的枚举类型。例如下面的 api-method 有参数resolution

public async Task<ActionResult<ReturnType>> GetData(Models.ResolutionEnum resolution)

这会为 swagger.json 生成以下操作参数定义(注意缺失x-EnumNames):

{
    name: "resolution",
    in: "query",
    required: true,
    type: "integer",
    format: "int32",
    enum: [
        1,
        2,
        3,
        4
    ]
}

是否有任何方法可以扩展作为方法参数一部分的 swagger 枚举模式?

标签: c#asp.net-coreenumsswaggerswashbuckle

解决方案


感谢this question下的另一个答案,我发现命名空间中有多个扩展点Swashbuckle.AspNetCore.SwaggerGenIParameterFilter正是我想要的,我能够注入x-enumNames方法参数定义。

以下是我制作的参数过滤器:

public class ModifyParametersFilter : IParameterFilter
{
    public void Apply(IParameter parameter, ParameterFilterContext context)
    {
        var type = context.ParameterInfo?.ParameterType;
        if (type == null)
            return;
        if (type.IsEnum)
        {
            var names = Enum.GetNames(type);
            var values = Enum.GetValues(type);
            var desc = "";

            foreach (var value in values)
            {
                var intValue = Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType()));
                desc += $"{intValue}={value},";
            }
            desc = desc.TrimEnd(',');
            if (!parameter.Extensions.ContainsKey("x-enumNames"))
                parameter.Extensions.Add("x-enumNames", names);
        }
    }
}

与其他过滤器一样,可以Startup.cs使用以下代码段激活它:

services.AddSwaggerGen(c =>
{
    ..
    c.ParameterFilter<ModifyParametersFilter>();
}

推荐阅读