Asp.net .core Web API版本控制不适用于网址路径段

时间:2019-05-29 09:17:30

标签: asp.net asp.net-web-api asp.net-core versioning

我事先在各种来源中搜索了我的问题,但是答案并没有为我提供解决方案。

我以here提出的方式在.net core 2.2项目中实现了基于URL的Web api版本控制。我用于版本控制的版本是最新的Microsoft.AspNetCore.Mvc.Versioning 3.1.2。 我还尝试从以下来源了解它的工作原理:source1source2source3source4

我在名为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并转到正确的请求时,我想念什么?

1 个答案:

答案 0 :(得分:0)

经过更多调试之后,我终于弄清了为什么它不起作用,因此我将解决方案发布给将面临类似问题的任何人。问题出在控制器继承之内。

我创建了一个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]属性不一致,即使我认为基本控制器根本不需要更改也是如此。而且,我在基本控制器中只有基本路由。

因此,我收到了“匹配多个动作”的错误。

我还发现,版本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的评论,他们将我引向了正确的方向。