Asp.net .core web api 版本控制不适用于 Url 路径段
Asp.net .core web api versioning does not work for Url path segment
我事先在各种来源中搜索了我的问题,但答案并没有为我提供解决方案。
我在 .net core 2.2 项目中实现了基于 Url 的 web api 版本控制 here。我用于版本控制的版本是最新的 Microsoft.AspNetCore.Mvc.Versioning 3.1.2。
我还试图从以下来源了解它是如何工作的:source1, source2, source3, source4.
我在名为 Initial 的文件夹中有一个带有 GET 方法的 ValueController,在名为 New 的文件夹中有一个 Value2Controller。这两个文件夹都是 'Controllers' 文件夹的子文件夹。
结构如下:
ValueController中的路由是
[Route("api/v{version:apiVersion}/[controller]")]
在 Value2Controller 中是:
[Route("api/v{version:apiVersion}/value")]
我还在 Startup.cs 中设置了 options.EnableEndpointRouting = false;
,我尝试调用 api/v1/value 或 api/v2/value。两次我都收到错误:多个操作匹配。它无法区分两个控制器的动作。
我尝试在没有任何选项的情况下使用 services.AddApiVersioning();
,并删除了 AddVersionedApiExplorer。这是行不通的。唯一有效的是
推杆
[Route("api/v{version:apiVersion}/[controller]")]
在两个控制器中进行以下 api 调用:
api/v1/value
和 api/v2/value2
.
我的startup.cs中的配置如下:
services.AddApiVersioning(options =>
{
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);
options.ApiVersionReader = new UrlSegmentApiVersionReader();
options.UseApiBehavior = true;
});
services.AddVersionedApiExplorer(
options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);
});
我错过了什么来调用 api/v1/value
或 api/v2/value
并转到正确的请求?
经过更多的调试,我终于弄清楚了为什么它不起作用,所以我将解决方案发布给将面临类似问题的任何人。问题出在控制器继承中。
我创建了一个 CustomBaseController(出于某种原因我完全忽略了它的问题),其中包含一些用于全局异常处理的方法,继承如下:
[ApiVersionNeutral]
[Route("api/[controller]")]
[ApiController]
CustomBaseController : Controller
和
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
ValuesController : CustomBaseController { // http method implementations}
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/values")]
[ApiController]
ValuesController : CustomBaseController { // updated http method implementations}
版本控制机制与 [ApiVersionNeutral]
属性不一致,尽管对我来说基本控制器根本不需要更改是有意义的。此外,我在基本控制器中只有基本路由。
因此我得到了 "Multiple actions matched" 的错误。
我还发现版本 1 控制器可以从基本控制器继承路由,并且没有理由在那里有路由。对于所有后续控制器,路由必须是:
[Route("api/v{version:apiVersion}/values")]
.
上面发布的初始配置的工作解决方案如下:
[Route("api/v{version:ApiVersion}/[controller]")]
[ApiController]
CustomBaseController: Controller {}
[ApiVersion("1.0")]
[ApiController]
ValuesController: CustomBaseController { //code }
[ApiVersion("2.0")]
[ApiController]
[Route("api/v{version:ApiVersion}/values")]
Values2Controller: CustomBaseController { //code }
[ApiVersion("3.0")]
[ApiController]
[Route("api/v{version:ApiVersion}/values")]
Values3Controller: CustomBaseController { //code }
从以下网址获取值:
api/v1/values
api/v2/values
api/v3/values
虽然我的问题已经解决了,但我还是不明白为什么 [ApiVersionNeutral] 会导致路由无法正确检测到其他控制器的版本。任何解释将不胜感激。
谢谢@Matt Stannett 的评论,他们引导我走向正确的方向。
我事先在各种来源中搜索了我的问题,但答案并没有为我提供解决方案。
我在 .net core 2.2 项目中实现了基于 Url 的 web api 版本控制 here。我用于版本控制的版本是最新的 Microsoft.AspNetCore.Mvc.Versioning 3.1.2。 我还试图从以下来源了解它是如何工作的:source1, source2, source3, source4.
我在名为 Initial 的文件夹中有一个带有 GET 方法的 ValueController,在名为 New 的文件夹中有一个 Value2Controller。这两个文件夹都是 'Controllers' 文件夹的子文件夹。
结构如下:
ValueController中的路由是
[Route("api/v{version:apiVersion}/[controller]")]
在 Value2Controller 中是:
[Route("api/v{version:apiVersion}/value")]
我还在 Startup.cs 中设置了 options.EnableEndpointRouting = false;
,我尝试调用 api/v1/value 或 api/v2/value。两次我都收到错误:多个操作匹配。它无法区分两个控制器的动作。
我尝试在没有任何选项的情况下使用 services.AddApiVersioning();
,并删除了 AddVersionedApiExplorer。这是行不通的。唯一有效的是
推杆
[Route("api/v{version:apiVersion}/[controller]")]
在两个控制器中进行以下 api 调用:
api/v1/value
和 api/v2/value2
.
我的startup.cs中的配置如下:
services.AddApiVersioning(options =>
{
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);
options.ApiVersionReader = new UrlSegmentApiVersionReader();
options.UseApiBehavior = true;
});
services.AddVersionedApiExplorer(
options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);
});
我错过了什么来调用 api/v1/value
或 api/v2/value
并转到正确的请求?
经过更多的调试,我终于弄清楚了为什么它不起作用,所以我将解决方案发布给将面临类似问题的任何人。问题出在控制器继承中。
我创建了一个 CustomBaseController(出于某种原因我完全忽略了它的问题),其中包含一些用于全局异常处理的方法,继承如下:
[ApiVersionNeutral]
[Route("api/[controller]")]
[ApiController]
CustomBaseController : Controller
和
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
ValuesController : CustomBaseController { // http method implementations}
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/values")]
[ApiController]
ValuesController : CustomBaseController { // updated http method implementations}
版本控制机制与 [ApiVersionNeutral]
属性不一致,尽管对我来说基本控制器根本不需要更改是有意义的。此外,我在基本控制器中只有基本路由。
因此我得到了 "Multiple actions matched" 的错误。
我还发现版本 1 控制器可以从基本控制器继承路由,并且没有理由在那里有路由。对于所有后续控制器,路由必须是:
[Route("api/v{version:apiVersion}/values")]
.
上面发布的初始配置的工作解决方案如下:
[Route("api/v{version:ApiVersion}/[controller]")]
[ApiController]
CustomBaseController: Controller {}
[ApiVersion("1.0")]
[ApiController]
ValuesController: CustomBaseController { //code }
[ApiVersion("2.0")]
[ApiController]
[Route("api/v{version:ApiVersion}/values")]
Values2Controller: CustomBaseController { //code }
[ApiVersion("3.0")]
[ApiController]
[Route("api/v{version:ApiVersion}/values")]
Values3Controller: CustomBaseController { //code }
从以下网址获取值:
api/v1/values
api/v2/values
api/v3/values
虽然我的问题已经解决了,但我还是不明白为什么 [ApiVersionNeutral] 会导致路由无法正确检测到其他控制器的版本。任何解释将不胜感激。 谢谢@Matt Stannett 的评论,他们引导我走向正确的方向。