有没有办法让 Swashbuckle 将 OData 参数添加到 Web API 2 IQueryable<T> 端点?

Posted

技术标签:

【中文标题】有没有办法让 Swashbuckle 将 OData 参数添加到 Web API 2 IQueryable<T> 端点?【英文标题】:Is there a way to get Swashbuckle to add OData parameters to Web API 2 IQueryable<T> endpoint? 【发布时间】: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 ...但我真的不确定在这种情况下它是否能给我带来任何好处。

【问题讨论】:

【参考方案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,                
        );
    

【讨论】:

以上是关于有没有办法让 Swashbuckle 将 OData 参数添加到 Web API 2 IQueryable<T> 端点?的主要内容,如果未能解决你的问题,请参考以下文章

将 WebApi 方法的参数标记为过时/不推荐用于 Swashbuckle / Swagger

带有 OAuth2 的 Swashbuckle.AspNetCore v1.0.0,流程:应用程序 -> IdentityServer4

Swashbuckle 是不是支持将自定义操作标签表示为 UI 中的徽章的方法?

Swashbuckle 5 找不到我的 ApiControllers

SwashBuckle/Swagger 隐藏了我的不可变属性

ASP.NET 核心:NSwag 与 Swashbuckle