我试图从
RoutingConstaints Sample和VersionedRoute实现
RoutingConstaints Sample,但是当我使用控制器时,版本化的属性不再有效.
对于代码示例,下载示例项目(或者只是从上面的链接中查看几个文件),然后修改路由:
// 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); } }
编辑:如果您需要更多信息,甚至发布想法或事情尝试,请让我知道:)
编辑2:这是我从Troy Hunt的博客中所做的一个例子:http://www.troyhunt.com/2014/02/your-api-versioning-is-wrong-which-is.html
编辑3:这是我想要的代码尽可能接近,因为它会减少很多的开销和魔术字符串.
[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版本头设置时收到响应)
以下代码将会在您的示例中的两个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); } }
一个改进是创建自己的属性而不是路由,所以你不需要在每个版本前缀:
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); } }