【问题标题】:Is there a way to get Swashbuckle to add OData parameters to Web API 2 IQueryable<T> endpoint?有没有办法让 Swashbuckle 将 OData 参数添加到 Web API 2 IQueryable<T> 端点?
【发布时间】:2017-06-17 19:42:03
【问题描述】:

我有一个支持 OData 查询的 ASP.Net Web API 2 端点。是这样的:

[HttpGet, Route("")]
public IQueryable<Thing> Get()
{
    return _thingsRepository.Query();
}

OData $filter 参数和这样的工作很棒。我只是希望他们能像实际的 OData 控制器一样出现在 Swagger 中。

我正在使用 Swashbuckle.OData ...但我真的不确定在这种情况下它是否能给我带来任何好处。

【问题讨论】:

    标签: asp.net asp.net-web-api2 odata swashbuckle


    【解决方案1】:

    事实证明,使用 IOperationFilter 使用 SwashBuckle 添加您想要 Swagger 的任何参数非常容易。您可以使用 c.OperationFilter&lt;ODataParametersSwaggerDefinition&gt;(); 将其添加到 Swagger 配置中。我创建了一个向我的 API 中的所有 IQueryable 端点添加一些 OData 参数的方法:

    /// <summary>
    ///     Add the supported odata parameters for IQueryable endpoints.
    /// </summary>
    public class ODataParametersSwaggerDefinition : IOperationFilter
    {
        private static readonly Type QueryableType = typeof(IQueryable);
    
        /// <summary>
        ///     Apply the filter to the operation.
        /// </summary>
        /// <param name="operation">The API operation to check.</param>
        /// <param name="schemaRegistry">The swagger schema registry.</param>
        /// <param name="apiDescription">The description of the api method.</param>
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            var responseType = apiDescription.ResponseType();
    
            if (responseType.GetInterfaces().Any(i => i == QueryableType))
            {
                operation.parameters.Add(new Parameter
                {
                    name = "$filter",
                    description = "Filter the results using OData syntax.",
                    required = false,
                    type = "string",
                    @in = "query"
                });
    
                operation.parameters.Add(new Parameter
                {
                    name = "$orderby",
                    description = "Order the results using OData syntax.",
                    required = false,
                    type = "string",
                    @in = "query"
                });
    
                operation.parameters.Add(new Parameter
                {
                    name = "$skip",
                    description = "The number of results to skip.",
                    required = false,
                    type = "integer",
                    @in = "query"
                });
    
                operation.parameters.Add(new Parameter
                {
                    name = "$top",
                    description = "The number of results to return.",
                    required = false,
                    type = "integer",
                    @in = "query"
                });
    
                operation.parameters.Add(new Parameter
                {
                    name = "$count",
                    description = "Return the total count.",
                    required = false,
                    type = "boolean",
                    @in = "query"
                });
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      直接窃取已接受的答案,但需要额外的空值检查。

      这不会触及您现有的 OData 可查询端点,这些端点可能已经定义了 parameters,但只会增强您的可查询 ApiController 端点。

       /// <summary>
       /// Adds the supported odata parameters for IQueryable endpoints 
       /// ONLY if no parameters are defined already.
       /// </summary>
       public class ODataParametersSwaggerDefinition : IOperationFilter
       {
          private static readonly Type QueryableType = typeof(IQueryable);
      
          /// <summary>
          /// Apply the filter to the operation.
          /// </summary>
          /// <param name="operation">The API operation to check.</param>
          /// <param name="schemaRegistry">The swagger schema registry.</param>
          /// <param name="apiDescription">The description of the api method.</param>
          public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
          {
              var responseType = apiDescription.ResponseType();
      
              if (responseType.GetInterfaces().Any(i => i == QueryableType))
              {
                  if (operation.parameters == null)
                  {
                      operation.parameters = new List<Parameter>();
      
                      operation.parameters.Add(new Parameter
                      {
                          name = "$filter",
                          description = "Filter the results using OData syntax.",
                          required = false,
                          type = "string",
                          @in = "query"
                      });
      
                      operation.parameters.Add(new Parameter
                      {
                          name = "$orderby",
                          description = "Order the results using OData syntax.",
                          required = false,
                          type = "string",
                          @in = "query"
                      });
      
                      operation.parameters.Add(new Parameter
                      {
                          name = "$skip",
                          description = "The number of results to skip.",
                          required = false,
                          type = "integer",
                          @in = "query"
                      });
      
                      operation.parameters.Add(new Parameter
                      {
                          name = "$top",
                          description = "The number of results to return.",
                          required = false,
                          type = "integer",
                          @in = "query"
                      });
      
                      operation.parameters.Add(new Parameter
                      {
                          name = "$count",
                          description = "Return the total count.",
                          required = false,
                          type = "boolean",
                          @in = "query"
                      });
                  }
      
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

        使用 Swashbuckle.AspNetCore v. 6.2.3 可以如下所示:

        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            if (context.MethodInfo.ReturnType.GetInterfaces().Any(i => i == typeof(IQueryable)))
            {
                operation.Parameters.Add(new OpenApiParameter()
                {
                    Name = "$filter",
                    Description = "My $filter filter",
                    Required = false,
                    In = ParameterLocation.Query,                
                });
        
                operation.Parameters.Add(new OpenApiParameter()
                {
                    Name = "$top",
                    Description = "My $top filter",
                    Required = false,
                    In = ParameterLocation.Query,           
                });
        
                operation.Parameters.Add(new OpenApiParameter()
                {
                    Name = "$expand",
                    Description = "My $top filter",
                    Required = false,
                    In = ParameterLocation.Query,                
                });
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2013-04-25
          • 2022-01-19
          • 1970-01-01
          • 2023-03-12
          • 1970-01-01
          • 1970-01-01
          • 2019-06-02
          • 2022-01-19
          • 2014-07-09
          相关资源
          最近更新 更多