一旦将 Swashbuckle 添加到 .NET Core Web API 应用程序,访问版本化路由 returns 404
Accessing versioned routes returns 404 once Swashbuckle is added to a .NET Core Web API application
我创建了一个最小可行样本来隔离我遇到的这个问题。我确定这是我缺少的东西,而不是工具本身。我正在寻求帮助以弄清楚我缺少什么以及如何解决它。
我有一个准系统 .NET Core 3.1 Web API。它包含 2 个控制器(版本 1 和版本 2),它们公开相同的端点并具有相同的名称:
- /api/v1/foo/status
- /api/v2/foo/status
如果我不将 Swashbuckle 添加到应用程序,我可以访问这些端点并通过网络浏览器看到预期的响应。 (响应为 HTTP 200,响应正文包含预期的文本。)
但是,一旦我将 Swashbuckle 添加到解决方案中,Swagger 页面就会出现并且一切看起来都很好,但我无法再通过 Swagger UI 或通过浏览器本身访问端点。
相反,如果使用 [Route('api/{version}/foo')]
在路由中指定版本,则响应为 HTTP 404,响应正文中包含以下内容:
{
"error": {
"code": "UnsupportedApiVersion",
"message": "The HTTP resource that matches the request URI 'http://localhost:3011/api/v2/foo/status' is not supported.",
"innerError": null
}
}
或者,如果使用 [Route('api/v2/foo')]
将版本硬编码到路由中,则响应为 HTTP 400,响应正文中包含以下内容:
{
"error": {
"code": "UnsupportedApiVersion",
"message": "The HTTP resource that matches the request URI 'https://localhost:44343/api/v2/foo/status' is not supported.",
"innerError": null
}
}
我已经尝试了我在各种博客文章、Whosebug 问题和 Microsoft 文章中找到的所有方法来使它正常工作,但都无济于事,包括以下内容:
- 为每个控制器添加
[ApiController]
。
- 为每个控制器添加
[ApiVersion]
。
- 在每个路由中明确包含
{version:apiVersion}
。
- 将
[MapToApiVersion]
添加到每个控制器操作。
- 在配置 SwaggerGen 时添加一个 DocumentFilter 和一个 OperationFilter。
到目前为止,没有任何解决方案奏效。
可以在 GitHub 中的以下位置找到包含 MVP 项目的解决方案:https://github.com/DreadLordMikey/NetCoreWebApiMVP
将两个控制器路由更改为:
[Route("api/v{version:apiVersion}/foo")]
并删除下面的options.SubstitutionFormat
:
services.AddVersionedApiExplorer(options =>
{
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
//options.SubstitutionFormat = "'v'VVV";
});
结果:
我创建了一个最小可行样本来隔离我遇到的这个问题。我确定这是我缺少的东西,而不是工具本身。我正在寻求帮助以弄清楚我缺少什么以及如何解决它。
我有一个准系统 .NET Core 3.1 Web API。它包含 2 个控制器(版本 1 和版本 2),它们公开相同的端点并具有相同的名称:
- /api/v1/foo/status
- /api/v2/foo/status
如果我不将 Swashbuckle 添加到应用程序,我可以访问这些端点并通过网络浏览器看到预期的响应。 (响应为 HTTP 200,响应正文包含预期的文本。)
但是,一旦我将 Swashbuckle 添加到解决方案中,Swagger 页面就会出现并且一切看起来都很好,但我无法再通过 Swagger UI 或通过浏览器本身访问端点。
相反,如果使用 [Route('api/{version}/foo')]
在路由中指定版本,则响应为 HTTP 404,响应正文中包含以下内容:
{
"error": {
"code": "UnsupportedApiVersion",
"message": "The HTTP resource that matches the request URI 'http://localhost:3011/api/v2/foo/status' is not supported.",
"innerError": null
}
}
或者,如果使用 [Route('api/v2/foo')]
将版本硬编码到路由中,则响应为 HTTP 400,响应正文中包含以下内容:
{
"error": {
"code": "UnsupportedApiVersion",
"message": "The HTTP resource that matches the request URI 'https://localhost:44343/api/v2/foo/status' is not supported.",
"innerError": null
}
}
我已经尝试了我在各种博客文章、Whosebug 问题和 Microsoft 文章中找到的所有方法来使它正常工作,但都无济于事,包括以下内容:
- 为每个控制器添加
[ApiController]
。 - 为每个控制器添加
[ApiVersion]
。 - 在每个路由中明确包含
{version:apiVersion}
。 - 将
[MapToApiVersion]
添加到每个控制器操作。 - 在配置 SwaggerGen 时添加一个 DocumentFilter 和一个 OperationFilter。
到目前为止,没有任何解决方案奏效。
可以在 GitHub 中的以下位置找到包含 MVP 项目的解决方案:https://github.com/DreadLordMikey/NetCoreWebApiMVP
将两个控制器路由更改为:
[Route("api/v{version:apiVersion}/foo")]
并删除下面的options.SubstitutionFormat
:
services.AddVersionedApiExplorer(options =>
{
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
//options.SubstitutionFormat = "'v'VVV";
});
结果: