简体   繁体   English

在确保 api 使用和不使用 api 版本时如何消除路由名称冲突?

[英]How to get rid of route-name conflicts when ensuring api works both with and without the api-version?

I want to apply asp.net api-versioning to my web app (which didn't have versioning).我想将 asp.net api-versioning 应用到我的 web 应用程序(没有版本控制)。 However, the tricky issue is that I must ensure that APIs should work both with and without the api-version.然而,棘手的问题是我必须确保 API 可以在有和没有 api 版本的情况下工作。

    [ApiVersion("1.0")]
    [Route("api/products/{productId}/[controller]")]
    [Route("api/v{version:apiVersion}/products/{productId}/[controller]")]
    [ValidateModel]
    [Produces("application/json")]
    public partial class ProductController : ControllerBase {

        internal const string GetLatestRoute = "GET Product/GetLatestAsync";

        [HttpGet(Name = GetLatestRoute)]
        public async Task<IActionResult> GetLatestAsync() {
        
        }
    }


I have a controller with multiple actions, each of them is defined with a unique route name.我有一个带有多个动作的控制器,每个动作都定义了一个唯一的路由名称。 When I add two routes (with and without versions) to the controller, there comes a route-name conflict error:当我向控制器添加两条路由(有和没有版本)时,会出现路由名称冲突错误:

Attribute routes with the same name 'GET Products/GetLatestAsync' must have the same template:具有相同名称“GET Products/GetLatestAsync”的属性路由必须具有相同的模板:

Action: 'Service.Controllers.ProductController.GetLatestAsync (ProductFD)' - Template: 'api/products/{productId}/Product'操作:'Service.Controllers.ProductController.GetLatestAsync (ProductFD)' - 模板:'api/products/{productId}/Product'

Action: 'Service.Controllers.ProductController.GetLatestAsync (ProductFD)' - Template: 'api/v{version:apiVersion}/products/{productId}/Product'操作:'Service.Controllers.ProductController.GetLatestAsync (ProductFD)' - 模板:'api/v{version:apiVersion}/products/{productId}/Product'

There are several answers on StackOverflow that say the issue can be solved by removing the route names defined for the action methods. StackOverflow 上有几个答案说这个问题可以通过删除为操作方法定义的路由名称来解决。 However, in my scenario, the route names are used to create Url Links in several places in the project.但是,在我的场景中,路由名称用于在项目的多个位置创建 Url 链接。

Is there an approach that I can get rid of the issue?有没有一种方法可以解决这个问题? I'm wondering whether I could append version to the route name variable or mapping the non-version api to the version/1.0 ...?我想知道我是否可以将版本附加到路由名称变量或将非版本 api 映射到 version/1.0 ...? On the other hand, there is a rare case that I update all the methods in a controller.另一方面,在极少数情况下我更新了控制器中的所有方法。 So is it possible that I only define a route-prefix on the top-level of the controller and only apply the api-version on the method-level?那么有没有可能我只在控制器的顶层定义一个路由前缀,而只在方法级别上应用 api-version?

Route names and the route table are not API version aware .路由名称和路由表不支持API 版本 In order for this to work, you need to use double route registration like you have because you are versioning by URL segment (not recommended).为了使其工作,您需要像您一样使用双路由注册,因为您是按 URL 段进行版本控制(不推荐)。 If clients are properly following the links returned by the server, then always using the route generated with the explicit version in it will do.如果客户端正确跟踪服务器返回的链接,则始终使用其中包含显式版本的路由即可。 If the client doesn't honor that and just calls the APIs directly without the API version, the second template will handle that for you.如果客户端不遵守这一点,而只是在没有 API 版本的情况下直接调用 API,则第二个模板将为您处理。 If you are only generating links with the same controller, then I would suggest using CreatedAtAction instead because it will not rely on the route name.如果您只生成具有相同控制器的链接,那么我建议改用CreatedAtAction因为它不依赖于路由名称。 If memory serves me correct, you can specify the order of each [Route] for precedence.如果没记错的话,您可以指定每个[Route]的优先顺序。 If unspecified, it will be the first attribute specified - which matters.如果未指定,它将是指定的第一个属性 - 这很重要。

You'll also need to enable:您还需要启用:

services.AddApiVersioning(options => options.AssumeDefaultVersionWhenUnspecified = true);

If you haven't already.如果你还没有。

Last, but not least, beware the known, breaking change: Async suffix trimmed from controller action names .最后但并非最不重要的一点是,要注意已知的重大更改: 从控制器操作名称中删除的 Async 后缀 This has snared many people.这让很多人陷入了困境。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在ASPNET MVC中使用路由的路由名称的位置 - where to use route-name of routing in aspnet mvc 在Web API中获取匹配的路由名称 - Get matched route name in Web API 在 httpcontext 中设置 api-version 以进行集成测试。[已经回答了类似的 SO 问题不适用于我] - Setting the api-version in httpcontext for integration tests.[Already answered similar SO question doesn't apply to me] 在路径控制器中时如何获取路径“名称” - How to get route “name” when in route controller 当我有一个同名文件夹时,如何创建Web Api 2 Route? - How can I create a Web Api 2 Route when I have a folder of the same name? Web API:如何在控制器操作没有相应参数时获取路由参数 - Web API: How to get a route parameter when controller action does not have corresponding argument 定义不带/ api / {controller}前缀的WebAPI路由 - Defining a WebAPI route without the /api/{controller} prefix RESTFul API 同时具有 FromRouteAttribute 和 FromQuery 的 Get 方法 - RESTFul API Get method with both FromRouteAttribute and FromQuery 将ASP.NET Web API托管为Windows服务时如何获取用户名 - How to get user name when ASP.NET web api hosted as windows service 当调用的方法属性不正确 web api c# 时,如何将当前路由重定向到另一条路由? - How to redirect current route to the another route when the call have method attribute incorrect web api c#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM