ASP NET Web API中的路由 – 适用于不同版本的API

我正在从这里阅读Attribute Routing in Web API 2

文章说,

 Here are some other patterns that attribute routing makes easy. API versioning In this example, “/api/v1/products” would be routed to a different controller than “/api/v2/products”. /api/v1/products /api/v2/products 

怎么会?

编辑:我会在正常路由中执行此操作

 public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/v2/products", defaults: new { controller = V2_Products } ); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/v1/products", defaults: new { controller = V1_Products } ); } } 

任何人都可以解释我如何在Attribute Routing方式中这样做? 为什么使用Attribute routing对于这个例子更容易和方便(根据文章)?

有许多方法可以使用属性路由实现版本控制; 一个非常基本的方法是为每个版本的ApiController使用RoutePrefix属性

 [RoutePrefix("v1")] public class V1_ProductsController : ApiController { [Route("products")] public IEnumerable Get() { return new string[] { "v1-product1", "v1-product2" }; } //.... } [RoutePrefix("v2")] public class V2_ProductsController : ApiController { [Route("products")] public IEnumerable Get() { return new string[] { "v2-product1", "v2-product2" }; } //.... } 

/v1/products转到第一版/v2/products转到第二版。

您可以通过重写DefaultHttpControllerSelector来实现

在那里你覆盖selectcontroller的方法

 public override HttpControllerDescriptor SelectController(HttpRequestMessage request) { HttpControllerDescriptor controllerDescriptor = null; IDictionary controllers = GetControllerMapping(); IHttpRouteData routeData = request.GetRouteData(); if (routeData == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } object apiVersion; if (!routeData.Values.TryGetValue("Version", out apiVersion)) { apiVersion = "1"; } object controllerName; if (!routeData.Values.TryGetValue("controller", out controllerName)) { controllerName = string.Empty; } if (controllerName == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } string newControllerName = String.Concat(controllerName.ToString(), "V", apiVersion); if (controllers.TryGetValue(newControllerName, out controllerDescriptor)) { return controllerDescriptor; } if (controllers.TryGetValue(controllerName.ToString(), out controllerDescriptor)) { return controllerDescriptor; } throw new HttpResponseException(HttpStatusCode.NotFound); } 

然后你要添加webapiconfig的路线

  config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{version}/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); 

并在webapiconfig中注册控制器选择器

 config.Services.Replace(typeof(IHttpControllerSelector), new ApiVersioningSelector(config)); 

所以从现在起如果你命名控制器ProductsV1Controller它将reffer / api / v1 / products。 另请注意,我的示例也支持没有版本的路由,因此如果找不到v1,它将尝试检查ProductsController是否存在

PS。 代码更新有一个bug就在那里:(

另一种简单的方法是将路由配置为api / {folder} / {controller} / {action},在文件夹中,您可以将名称命名为V1或V2。

一个好方法是实现自己的Controller选择器。 您可以使用此链接获取更多信息。

Web API用于选择控制器的接口是IHttpControllerSelector 。 此接口上的重要方法是SelectController,它为给定的HttpRequestMessage选择一个控制器。