【问题标题】:Swashbuckle SchemaFilter for api operation parametersSwashbuckle SchemaFilter 用于 api 操作参数
【发布时间】:2019-09-14 21:01:34
【问题描述】:

我已成功创建 ISchemaFilter 来扩展 swagger.json 枚举属性定义以用于代码生成目的,如 here 所述。这是我目前的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-core enums swagger swashbuckle


    【解决方案1】:

    感谢another answer在这个问题下,我发现Swashbuckle.AspNetCore.SwaggerGen命名空间中有多个扩展点。 IParameterFilter 正是我想要的,我能够将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 中使用以下 sn-p 激活:

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

    【讨论】:

      【解决方案2】:

      尝试使用 IDocumentFilter,我已经使用它注入了 x-stuff,这是一个示例:

      public class InjectXStuff : IDocumentFilter
      {
          public void Apply(SwaggerDocument s, DocumentFilterContext c)
          {
              PathItem path = s.Paths.Where(x => x.Key.Contains("Values")).First().Value;
              path.Post.Parameters.FirstOrDefault().Extensions.Add("x-stuff", "123456");
          }
      }
      

      问题是您需要提前知道路径,不确定是否有可以在代码中使用的模式来识别那些枚举...

      【讨论】:

      • 我试过这个并发现实际上更好的方法感谢您的提示。有多个扩展点,IParameterFilter 仅扩展方法参数。我会根据我的发现写另一个答案..
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多