2016-11-04 59 views
0

我有一本我編寫併發布的ASP.NET Web API。現在,我們正在考慮做一些改進,這些改進涉及對某些調用的更改,這意味着我們需要進行版本控制以保持現有客戶端的正常運行。ASP.NET Web API中的API版本

我已經在我的應用程序中使用了屬性路由。方法由:Controller/Action通過RoutePrefix和Route屬性調用。

當我確實需要創建我的類的V2時,我只想重新創建實際更改的類,並將其他路由重定向回v1類,因爲它們沒有更改。 (否則,我只是結束了大量的樣板代碼或重複的代碼)。

我想要做的是有以下路線的班我的V1版本工作: 控制器/動作

對於V2我想任何新班赴V2,任何類,並沒有改變我想從V1類返回HttpControllerDescriptor。該路線看起來像v2/Controller/Action,但會重定向到Controller/Action。

我已經實現了一個IHttpControllerSelector並返回相應的HttpControllerDescriptors,但它沒有將該調用放入該方法。我相信它是因爲路由信息與操作不匹配。 (當我把一個IHttpActionSelector放入並跟蹤異常時,它說「發現了多個匹配請求的動作)。

所以,我想我想知道:這是否可能?這是最好的方式實現我想要做什麼?

+0

這可能會幫助你:http://www.culbertsonexchange.com/wp/?p = 318。如果你想實現你提到的問題,你必須實現你自己的屬性路由選擇邏輯。 –

回答

0

下面是我在asp.net web api中爲版本控制實現的內容。注意事項我沒有在WebApiConfig.cs中使用屬性路由,而是使用顯式路由,所以如果您想遵循這個模式你需要切換回顯式路由,而且我不喜歡實際路由中的版本信息,我在Accept頭中使用了一個自定義的(即「版本」)參數,我還將每個MIME類型的版本設置爲下面的例子:如果客戶端沒有設置版本號,或者請求的版本不存在,回落到默認控制器。

  1. 創建一個類,並從DefaultHttpControllerSelector繼承,所以你可以回退到基類的行爲,當你想。

  2. SelectController覆蓋方法,例如:

    公共覆蓋HttpControllerDescriptor SelectController(HttpRequestMessage請求) {

IDictionary的控制器= GetControllerMapping(); IHttpRouteData routeData = request.GetRouteData();

   string controllerName = (string)routeData.Values["controller"]; 

       HttpControllerDescriptor controllerDescriptor; 

       if (string.IsNullOrWhiteSpace(controllerName)) 
       { 
        return base.SelectController(request); 
       } 

       if (!controllers.TryGetValue(controllerName, out controllerDescriptor)) 
       { 
        return null; 
       } 

       string version = GetVersionFromAcceptHeader(request); 
       if (string.Equals(version, "1")) 
       { 
        return controllerDescriptor; 
       } 

       string newName = string.Concat(controllerName, "V", version); 

       HttpControllerDescriptor versionedControllerDescriptor; 
       if (controllers.TryGetValue(newName, out versionedControllerDescriptor)) 
       { 
        return versionedControllerDescriptor; 
       }   

       return controllerDescriptor; 
      } 
  • 註冊在webapiconfig該控制器選擇Register方法:

    config.Services.Replace(typeof運算(IHttpControllerSelector),新YourControllerSelector(配置));