将查询字符串参数添加到我的Swagger规格

iqih9akk  于 2022-11-06  发布在  其他
关注(0)|答案(4)|浏览(194)

我正在使用Swashbuckle(C#的swagger)和我的Web API。我有几个返回列表的GET端点,并且我允许用户在QueryString中添加每页和页面参数
示例:http://myapi.com/endpoint/?page=5&perpage=10
我看到swagger确实支持“查询”中的参数,但我如何让Swashbuckle做到这一点呢?
我在其中一条评论中提到,我通过创建一个自定义属性来解决了这个问题,这样我就可以做我需要做的事情。下面是我的解决方案的代码:

[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
public class SwaggerParameterAttribute : Attribute
{
    public SwaggerParameterAttribute(string name, string description)
    {
        Name = name;
        Description = description;
    }

    public string Name { get; private set; }
    public Type DataType { get; set; }
    public string ParameterType { get; set; }
    public string Description { get; private set; }
    public bool Required { get; set; } = false;
}

将属性注册到Swagger Config:

GlobalConfiguration.Configuration 
    .EnableSwagger(c =>
        {
            c.OperationFilter<SwaggerParametersAttributeHandler>();
        });

然后将此属性添加到方法中:

[SwaggerParameter("page", "Page number to display", DataType = typeof(Int32), ParameterType = ParameterType.inQuery)]
[SwaggerParameter("perpage","Items to display per page", DataType = typeof(Int32), ParameterType = ParameterType.inQuery)]
5m1hhzi4

5m1hhzi41#

你可以很容易地做到这一点。假设你有一个ItemsController,它有这样一个动作:

[Route("/api/items/{id}")]
public IHttpActionResult Get(int id, int? page = null, int? perpage = null)
{
   // some relevant code
   return Ok();
}

旋转扣将生成本规范(仅显示相关部分):

"paths":{  
  "/api/items/{id}":{  
     "get":{  
        "parameters":[  
           {  
              "name":"id",
              "in":"path",
              "required":true,
              "type":"integer",
              "format":"int32"
           },
           {  
              "name":"page",
              "in":"query",
              "required":false,
              "type":"integer",
              "format":"int32"
           },
           {  
              "name":"limit",
              "in":"query",
              "required":false,
              "type":"integer",
              "format":"int32"
           }
        ]
     }
  }

当您希望pageperpage成为必需参数时,只需使这些参数不可为空即可。

nzk0hqpo

nzk0hqpo2#

下面是Attribute方法所需步骤的摘要(ASP.NetCore2.1,Swashbuckle.AspNetCorev4.0.1)。我需要一个以“$”开头的参数,所以可选参数不是一个选项!
SwaggerParameterAttribute.cs

[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
     public class SwaggerParameterAttribute : Attribute
     {
         public SwaggerParameterAttribute(string name, string description)
        {
            Name = name;
            Description = description;
        }

        public string Name { get; private set; }
        public string DataType { get; set; }
        public string ParameterType { get; set; }
        public string Description { get; private set; }
        public bool Required { get; set; } = false;
    }

SwaggerParameterAttributeFilter.cs

using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Linq;
public class SwaggerParameterAttributeFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        var attributes = context.MethodInfo.DeclaringType.GetCustomAttributes(true)
            .Union(context.MethodInfo.GetCustomAttributes(true))
            .OfType<SwaggerParameterAttribute>();

        foreach (var attribute in attributes)
            operation.Parameters.Add(new NonBodyParameter
            {
                Name = attribute.Name,
                Description = attribute.Description,
                In = attribute.ParameterType,
                Required = attribute.Required,
                Type = attribute.DataType
            });              
    }
}

在启动.配置服务中添加此内容

using Swashbuckle.AspNetCore.Swagger;
 services.AddSwaggerGen(c =>
 {
      c.OperationFilter<SwaggerParameterAttributeFilter>();
      c.SwaggerDoc("v1.0", new Info { Title = "My API", Version = "v1.0" });
 });

并这样使用:

[SwaggerParameter("$top", "Odata Top parameter", DataType = "integer", ParameterType ="query")]

数据类型可以是:整数、字符串、布尔值
参数类型:可以是路径、正文、查询

vwkv1x7d

vwkv1x7d3#

这里有一些关于SwaggerParametersAttributeHandler缺少信息的注解。它是一个操作过滤器,可以帮助您确定如何处理属性。
下面是我使用的一个示例处理程序,它允许我使用SwaggerParameterAttribute覆盖可为空的参数的必需字段。

public class RequiredParameterOverrideOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        // Get all SwaggerParameterAttributes on the method
        var attributes = apiDescription.ActionDescriptor.GetCustomAttributes<SwaggerParameterAttribute>();

        if (operation.parameters == null)
        {
            operation.parameters = new List<Parameter>();
        }

        // For each attribute found, find the operation parameter (this is where Swagger looks to generate the Swagger doc)
        // Override the required fields based on the attribute's required field
        foreach (var attribute in attributes)
        {
            var referencingOperationParameter = operation.parameters.FirstOrDefault(p => p.name == attribute.Name);

            if (referencingOperationParameter != null)
            {
                referencingOperationParameter.required = attribute.Required;
            }
        }
    }
}
kknvjkwl

kknvjkwl4#

我知道这是一个老办法,但我花了一些时间寻找更简单的方法,并找到了它。所以,对于任何人谁也跌跌撞撞到这个老线索,这里是:

public async Task<IActionResult> Foo([FromQuery]YourDtoType dto)

相关问题