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/valueapi/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/valueapi/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 的评论,他们引导我走向正确的方向。