2015-04-05 57 views
1

我想使用基於URL的版本爲我的控制器網絡API 2。我發現的最佳解決方案是以下代碼。 我正在尋找更好的解決方案。我試圖限制它沒有工作 也許我做了一些事情不對我唯一關心的是在不同的命名空間使用控制器相同的名稱...?! 我userd字符串合併創建想要的類型。可能這不是一個好主意。 請對這個主題的很好的參考,如果你知道的任何.....?控制器版本使用URL

public class ControllerVersioning : DefaultHttpControllerSelector 
    { 
     private HttpConfiguration _config; 
     public ControllerVersioning(HttpConfiguration config) 
      : base(config) 
     { 
      _config = config; 
     } 

     public override HttpControllerDescriptor SelectController(HttpRequestMessage request) 
     { 
      var routeData = request.GetRouteData(); 

      var controllerName = routeData.Values["controller"].ToString(); 
      controllerName = char.ToUpper(controllerName[0]) + controllerName.Substring(1); 
      var versionName = routeData.Values["version"].ToString(); 

      HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(); 
      controllerDescriptor.Configuration = _config; 
      controllerDescriptor.ControllerName = controllerName; 

      string s = "ngolforoushan.Web.Api.Controllers.V" + versionName + "." + controllerName + "Controller"; 
      Type t=Type.GetType(s); 
      controllerDescriptor.ControllerType = t; 

      return controllerDescriptor; 

     } 
    } 
+0

看看這裏實現的VersionedRoute屬性:http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/RoutingConstraintsSample/RoutingConstraints.Server/Controllers/CustomerVersion1Controller.cs – 2015-04-05 21:09:18

+0

感謝您的回覆,但是, codeplex代碼與控制器有着不同的名稱,這很容易;-) – 2015-04-06 05:13:30

回答

2
var dictionary = new Dictionary<string, HttpControllerDescriptor>(StringComparer.OrdinalIgnoreCase); 

    var assembliesResolver = _config.Services.GetAssembliesResolver(); 
    var controllerResolver = _config.Services.GetHttpControllerTypeResolver(); 

    var controllerTypes = controllerResolver.GetControllerTypes(assembliesResolver); 

    foreach (var cType in controllerTypes) 
    { 
     var segments = cType.Namespace.Split(Type.Delimiter); 

     var controllerName = cType.Name.Remove(cType.Name.Length - DefaultHttpControllerSelector.ControllerSuffix.Length); 

     var controllerKey = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", segments[segments.Length - 1], controllerName); 
     if (!dictionary.Keys.Contains(controllerKey)) 
     { 
      dictionary[controllerKey] = new HttpControllerDescriptor(_config, cType.Name, cType); 
     } 
    } 

這是你可以返回你的所有組件控制器的列表,並把他們全部字典的方式。

根據我上面的代碼,我的意思是線程的話題,我的第一次後,你知道你可以得到{版本,控制器}和選擇相關的控制器,並把它當作一個參數。

我添加以下代碼,使其更容易獲取的版本和控制器,但你要知道,如果你有,他們是不相關的版本,你需要分配之前版本和控制器串檢查不同的路線。

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

爲了實現這個,控制器或方法的命名約定是什麼? – devlord 2015-12-03 19:17:38

1

在MVC5或更高版本可以使用屬性路由...

[路線( 「API/V1/AC1」)

[路線( 「API/V2/AC1」) ]