Web Api 2 API无法识别路由的多个属性(版本控制)
我正在尝试从RoutingConstaints Sample实现属性路由和VersionedRoute
,但是当我在控制器上使用两者时,版本化属性不再起作用。
我需要修改属性以使其与属性路由一起使用?
对于代码示例,请下载示例项目(或者只查看上面链接中的几个文件),然后修改路由:
// When I use the RoutePrefix, VersionedRoute no longer works (Sending "Api-Version" through http header doesn't route correctly // If I remove the RoutePrefix I can use VersionedRoute again // What do I need to change in its code to be able to use both? [VersionedRoute("api/Customers", 1)] // This route would be used as http://url/api/customers with a header of "api-version: 1" [RoutePrefix("api/v1/Customers")] // This route would be used purely through url versioning of http://url/api/v1/Customers public class CustomersV1Controller : ApiController { /* Other stuff removed */ [VersionedRoute("api/Customer", 1)] // I'd rather not have to use this here at all and just use a single one on the class, but having both nor just one on either works right now. [Route("")] public IHttpActionResult Get() { return Json(_customers); } }
VersionedRoute代码
VersionConstraint代码
编辑:如果您需要更多信息,甚至发布想法或事情,请告诉我:)
编辑2:这是我试图从特洛伊亨特的博客做的一个例子: http : //www.troyhunt.com/2014/02/your-api-versioning-is-wrong-which-is.html
Edit3:这是我想要编写的代码,因为它会减少大量的开销和魔术字符串。
[VersionedRoute("api/Customers", 1)] // This route would be used as http://url/api/customers with a header of "api-version: 1" [RoutePrefix("api/v1/Customers")] // This route would be used purely through url versioning of http://url/api/v1/Customers public class CustomersV1Controller : ApiController { /* Other stuff removed */ [Route("")] public IHttpActionResult Get() { // Removed return Ok(customers); } [Route("{id:int}")] public IHttpActionResult GetById(int id) { // Removed return Ok(customer); } } [VersionedRoute("api/Customers", 2)] // This route would be used as http://url/api/customers with a header of "api-version: 2" [RoutePrefix("api/v2/Customers")] // This route would be used purely through url versioning of http://url/api/v2/Customers public class CustomersV2Controller : ApiController { /* Other stuff removed */ [Route("")] public IHttpActionResult Get() { // Removed return Ok(customersThatAreDifferentThanV1); } [Route("{id:int}")] public IHttpActionResult GetById(int id) { // Removed return Ok(customerThatIsDifferent); } }
编辑:上次碰撞,尝试只需要在每个路径上编写一次路径版本信息,在控制器属性级别而不是每个操作。
Route
和VersionedRoute
属性一起正常工作,但您的RoutePrefix
属性也适用于您的VersionedRoute
(尝试访问/ api / v1 / Customers / api / Customer – 当设置api-version标头时,您将收到响应)
以下代码将针对示例中返回正确响应的两个URL产生所需的行为,但显然这并不能解决您想要在类顶部使用一个VersionedRoute
和一个RoutePrefix
问题。 为此需要另一种方法。 但是,您可以为不同的api版本提供单独的控制器。
[RoutePrefix("api")] public class CustomersV1Controller : ApiController { /* Other stuff removed */ [VersionedRoute("Customers", 1)] [Route("v1/Customers")] public IHttpActionResult Get() { return Json(_customers); } }
改进是创建自己的属性而不是Route
这样您就不需要每次都为版本添加前缀:
public class CustomVersionedRoute : Attribute, IHttpRouteInfoProvider { private readonly string _template; public CustomVersionedRoute(string route, int version) { _template = string.Format("v{0}/{1}", version, route); } public string Name { get { return _template; } } public string Template { get { return _template ; } } public int Order { get; set; } } [RoutePrefix("api")] public class CustomersV2Controller : ApiController { /* Other stuff removed */ [VersionedRoute("Customers", 2)] [CustomVersionedRoute("Customers", 2)] public IHttpActionResult Get() { return Json(_customers); } }