【问题标题】:ASP.NET Web API versioning with URL Query gives "duplicate route" error带有 URL 查询的 ASP.NET Web API 版本控制给出“重复路由”错误
【发布时间】:2019-01-10 01:25:24
【问题描述】:

首先,一点免责声明:我已经在aspnet-api-versioning repo 上为此创建了一个 GitHub 问题。这个问题的内容和那个github issue的内容基本一致。

我在 .NET 4.5.2 上使用 ASP.NET Web API。

我的示例 API 如下所示:

namespace App.Backend.Controllers.Version1
{
    [ApiVersion("1.0")]
    public class SomeController: ApiController
    {
        [HttpGet]
        [Route("api/entity/{id:int:min(1)}")]
        public async Task<IHttpActionResult> ApiAction(int id) //Already running in production
        {
            //Accessible by using ?api-version=1.0 OR by omitting that since this is the default version
            return Ok();
        }
    }
}

namespace App.Backend.Controllers.Version2
{
    [ApiVersion("2.0")]
    public class SomeController : ApiController
    {
        [HttpGet]
        [Route("api/entity/{id:int:min(1)}")]
        public async Task<IHttpActionResult> ApiAction(int id)
        {
            //Accessible by using ?api-version=2.0 OR by omitting that since this is the default version
            return Ok();
        }
    }
}

配置如下:

// Add versioning
config.AddApiVersioning(o => 
{
    o.AssumeDefaultVersionWhenUnspecified = true;
    o.DefaultApiVersion = new ApiVersion(1, 0);
});

但是,当我发送请求时,会发生以下情况:

System.InvalidOperationException: A route named 'RegisterHours' is already in the route collection. Route names must be unique.

重复:

api/some/ApiAction
api/some/ApiAction

这对我来说很奇怪,因为在 wiki there is an example 完全是就像我的情况

我想使用?api-version={version} 选项,但看起来我现在别无选择使用 URL 路径版本(api/v1.0/some/apiActionapi/v2.0/some/apiAction。如果这是真的,我想我必须添加另一个路由到每个现有的操作都会像 api/v{version:apiVersion}/controller/action 一样允许他们使用 v1.0 以便在整个应用程序中统一?

你们有什么建议?我猜我可以在 API 版本 2 的 URL 中使用 /v2.0/,但我更喜欢查询字符串版本。

【问题讨论】:

    标签: c# asp.net rest asp.net-web-api versioning


    【解决方案1】:

    示例中没有显示,但是报错信息:

    System.InvalidOperationException:名为“RegisterHours”的路由已在路由集合中。路由名称必须是唯一的。

    表示路由表中有多个同名条目。如果我不得不猜测,属性路由实际上被定义为:

    [Route("api/entity/{id:int:min(1)}", Name = "RegisterHours")]
    

    ...或类似的东西。

    很遗憾,路由表不是 API 版本感知。路由表中的名称必须是唯一的。当您在 RouteAttribute 中指定名称时,会导致此问题。唯一真正的解决方法是使用唯一的路线名称;例如,Name = "RegisterHoursV1"Name = "RegisterHoursV2"

    除此之外:你不需要:

    var constraintResolver = new DefaultInlineConstraintResolver()
    {
        ConstraintMap = { ["apiVersion"] = typeof( ApiVersionRouteConstraint ) }
    };
    configuration.MapHttpAttributeRoutes( constraintResolver );
    

    除非您按 URL 段进行版本控制。

    【讨论】:

      【解决方案2】:

      修复重复的“RegisterHours”后(根据 git hub 问题页面响应),您还应该确保在 startup.cs 中设置了 constraintResolver

          public void Configuration( IAppBuilder builder )
          {
              // we only need to change the default constraint resolver for services that want urls with versioning like: ~/v{version}/{controller}
              var constraintResolver = new DefaultInlineConstraintResolver() { ConstraintMap = { ["apiVersion"] = typeof( ApiVersionRouteConstraint ) } };
              var configuration = new HttpConfiguration();
              var httpServer = new HttpServer( configuration );
      
              // reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
              configuration.AddApiVersioning( o => o.ReportApiVersions = true );
              configuration.MapHttpAttributeRoutes( constraintResolver );
              builder.UseWebApi( httpServer );
          }
      

      否则,您更改路由的属性 (api/entity) 将不起作用,因为路由与控制器名称“Some”不匹配,因此与默认路由不匹配,即。 ~\api\控制器名称\

      public class ***Some***Controller : ApiController
      {
          [HttpGet]
          [Route( "api/***entity***/{id:int:min(1)}" )]    <--- won't work without the constraint resolver
          public async Task<IHttpActionResult> ApiAction( int id )
          {
              //Accessible by using ?api-version=2.0 OR by omitting that since this is the default version
              return Ok();
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-03
        • 2016-07-17
        • 2018-02-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多