有没有办法让 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<ODataParametersSwaggerDefinition>();
将其添加到 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