2015-12-15 45 views
0

我一直在嘗試在Web API 2.2(5.2.3)中實現版本化路由,其中​​當選擇特定操作時,控制器的較新版本優先於先前版本路線。ASP.NET Web API 2繼承版本化路由

例如鑑於以下控制器類hierarcy:

namespace MyApi.Controllers.V1 { 
    public class FooController { 
     protected IFooRepository Repo; // Assume Repo is injected via IoC 

     [Route("{id:int:min(1)}")] 
     public IFoo GetSingle(int id) { 
      Repo.Single(new FooSearchOpts { Id = id }); 
     } 

     public IEnumerable<IFoo> GetAll() { 
      Repo.Search(); 
     } 
    } 
} 

namespace MyApi.Controllers.V3 { 
    public class FooController : V1.FooController { 
     public IEnumerable<IFoo> Search(string type) { 
      Repo.Search(new FooSearchOpts { Type = type }); 
     } 
    } 
} 

namespace MyApi.Controllers.V4 { 
    public class FooController : V3.FooController { 
     public IEnumerable<IFoo> SearchV4(string type, string name) { 
      Repo.Search(new FooSearchOpts { 
       Type = type, 
       Name = name 
      }); 
     } 
    } 
} 

namespace MyApi.Controllers.V5 { 
    public class FooController : V4.FooController { 
     /* nothing relevant */ 
    } 
} 

我可以得到一些路線通過創建自定義IHttpControllerSelector讀取從路由數據{version}工作(例如GET /api/v*/foo/123始終指向GetSingle)。

當控制器的不同版本中存在多個可能的路由時,會出現此問題。我需要請求GET /api/v*/foo選擇以下方法:

/api/v1/foo - >V1.FooController.GetAll
/api/v2/foo - >V1.FooController.GetAll
/api/v3/foo - >V3.FooController.Search
/api/v4/foo - >V4.FooController.SearchV4
/api/v5/foo - >V5.FooController.SearchV4

只要指定一個自定義控制器選擇器理解抱怨重複/模糊行爲,但我找不到任何當我指定自定義IHttpActionSelector時,保留現有動作選擇邏輯的方法。我真的需要手動重新實現所有的方法名解析和參數檢查嗎?還是有辦法利用現有的邏輯?

不幸的是我不能發佈所有的東西我已經更主要的路由配置看起來是這樣的:

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     // VersionedRouteProvider specifies a global route prefix of "api/v{version}/{ctrl}" 
     config.MapHttpAttributeRoutes(new VersionedRouteProvider()); 

     // VersionedControllerSelector uses {version} and {ctrl} to map out controllers 
     var controllerSelector = new VersionedControllerSelector(config); 
     config.Services.Replace(typeof(IHttpControllerSelector), controllerSelector); 

     // VersionedActionSelector creates actions from controllers, 
     // currently it would require iterating MethodInfos 
     // and manually creating all HttpActionDescriptors 
     // based on the methods' names and parameters 
     config.Services.Replace(typeof(IHttpActionSelector), new VersionedActionSelector(controllerSelector)); 
    } 
} 

我看着創建自定義IDirectRouteProviderIDirectRouteFactory,但它似乎像我d仍然需要定製IHttpActionSelector來處理不明確的路線。

謝謝。

回答

1

版本控制不應該以這種方式工作,或者您可以禁用所有的用戶代碼,因爲它們會得到與以前不同的結果。版本控制應該使用屬性路由(api/v2/whatever)來完成,以允許api的使用者根據自己的選擇切換到新版本。

[HttpGet, Route("api/v1/users") 
public IHttpActionResult UsersVersion1() {} 

[HttpGet, Route("api/v2/users") 
public IHttpActionResult UsersVersion2() {} 
+0

用戶仍然指定的URL API版本明確,就像在你的榜樣,只是路由是基於命名空間和類層次結構,而不必手動複製/粘貼的版本不必之間和潛在的相同方法用路由屬性手動註釋所有內容。 –