在确保api在使用和不使用api版本的情况下都能工作时,如何消除路由名称冲突



我想将asp.net api版本控制应用于我的web应用程序(它没有版本控制(。然而,棘手的问题是,我必须确保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() {

}
}

我有一个有多个动作的控制器,每个动作都定义了一个唯一的路由名称。当我向控制器添加两个路由(有版本和没有版本(时,会出现路由名称冲突错误:

具有相同名称"GET Products/GetLatestAsync"的属性路由必须具有相同的模板:

操作:"Service.Controllers.ProductController.GetLatestAsync(ProductFD("-模板:"api/products/{productId}/Product">

操作:"Service.Controllers.ProductController.GetLatestAsync(ProductFD("-模板:"api/v{version:apiVersion}/products/{productId}/Product">

StackOverflow上有几个答案说,可以通过删除为操作方法定义的路由名称来解决这个问题。然而,在我的场景中,路由名称用于在项目中的多个位置创建Url链接。

有没有一种方法可以让我摆脱这个问题?我想知道我是否可以将版本附加到路由名称变量,或者将非版本api映射到版本/1.0。。。?另一方面,有一种罕见的情况是,我更新控制器中的所有方法。那么,我是否可能只在控制器的顶层定义一个路由前缀,而只在方法级别应用api版本?

路由名称和路由表不支持API版本。为了实现这一点,您需要像以前一样使用双路由注册,因为您是按URL段进行版本控制的(不推荐(。如果客户端正确地遵循服务器返回的链接,那么总是使用其中包含显式版本的路由即可。如果客户端不遵守这一点,只在没有API版本的情况下直接调用API,则第二个模板将为您处理这一问题。如果您只使用相同的控制器生成链接,那么我建议使用CreatedAtAction,因为它不依赖于路由名称。如果记忆正确,您可以指定每个[Route]的优先级。如果未指定,它将是指定的第一个属性,这很重要。

您还需要启用:

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

如果你还没有。

最后,但同样重要的是,要注意已知的、破坏性的更改:从控制器操作名称中修剪出异步后缀。这已经诱捕了许多人。

最新更新