我有一个 ASP.NET Core (3.1) API,它使用aspnet-api-versioning (4.1.1) 库进行版本控制。该项目设置为从 URL 读取版本,如果未指定版本,则使用默认版本 (1)。示例控制器支持两个 API 版本(1 和 2)并且有两个相同的方法,每个版本一个。由于支持默认版本,因此控制器上有两个 Route 属性,一个没有版本,一个有。
在为 API 生成 OpenAPI 文档时,使用Swashbuckle.AspNetCore (5.6.3) 库,API 版本 1 和 2 的文档都将包含非版本化路由;“/客户/{externalCustomerId}”。要解决的问题是,如何将 Swagger 生成配置为仅包含默认版本的文档中的非版本化路由?鉴于下面的代码,版本 1 的文档应该是:
- /客户/{externalCustomerId}
- /v1/Customer/[externalCustomerId}
并且版本 2 的文档应该是:
- /v2/Customer/{externalCustomerId}
启动:
public class Startup
{
... // Removed for brevity. Method below called from ConfigureServices(...).
private static void ConfigureApiVersioning(IServiceCollection services)
{
services.AddVersionedApiExplorer(setup =>
{
setup.GroupNameFormat = "'v'V";
setup.SubstituteApiVersionInUrl = true;
});
services.AddApiVersioning(setup =>
{
setup.AssumeDefaultVersionWhenUnspecified = true;
setup.DefaultApiVersion = new ApiVersion(majorVersion: 1, minorVersion: 0);
setup.ReportApiVersions = true;
setup.ApiVersionReader = new UrlSegmentApiVersionReader();
});
}
}
控制器:
[Route("Customer")]
[Route("v{version:apiVersion}/Customer")]
[ApiVersion("1", Deprecated = true)]
[ApiVersion("2")]
[ApiController]
public class CustomerController : ControllerBase
{
[HttpGet("{externalCustomerId}")]
[MapToApiVersion("1")]
public string Get()
{
return "Customer Api v1 responded with 200 ok";
}
[HttpGet("{externalCustomerId}")]
[MapToApiVersion("2")]
public string GetV2()
{
return "Customer Api v2 responded with 200 ok";
}
}
可以(应该)以SwaggerGenOptions.DocInclusionPredicate()
某种方式解决它吗?我试了一下,但找不到从ApiVersion
谓词中获取默认 API 版本的方法。
一种选择可能是从DefaultApiVersionDescriptionProvider
(或实现IApiVersionDescriptionProvider
)继承来访问 Options 属性,这将允许我们获取默认 API 版本并在 Startup for 中使用带有闭包的谓词SwaggerGenOptions.DocInclusionPredicate()
,但这是一个好方法吗?还有哪些其他选择?