2013-10-23 13 views
8

Trong WebApiConfig.cs tôi đã sauNhận tên điều khiển

public static void Register(HttpConfiguration config) 
{ 

    config.MapHttpAttributeRoutes(); 

    config.Services.Replace(typeof(IHttpControllerSelector), 
       new MyApiControllerSelector(config)); 

    //code omitted for brevity 
} 

sau đó trong MyApiControllerSelector.cs tôi muốn có được bộ điều khiển

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

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

      //code omitted for brevity 
     } 

Khá đơn giản và nó làm việc rất lớn nhưng bây giờ sử dụng định tuyến thuộc tính tôi nghĩ rằng nó cần một cách tiếp cận khác? - như tôi dường như không thể tìm thấy một cách đơn giản

Tôi đã thử

var controllerName = request.GetActionDescriptor().ControllerDescriptor.ControllerName; 

mà không hoạt động.

Sau đó đọc source với gỡ lỗi đưa tôi đến với request.GetRouteData().Values["MS_SubRoutes"]

Vì vậy, bây giờ tôi có

string subRoutesKey = "MS_SubRoutes"; 

var attributedRoutesData = routeData.Values[subRoutesKey] as IEnumerable<IHttpRouteData>; 
var subRouteData = attributedRoutesData.FirstOrDefault(); 

var actions = (ReflectedHttpActionDescriptor[])subRouteData.Route.DataTokens["actions"]; 
var controllerName = actions[0].ControllerDescriptor.ControllerName; 

mà hoạt động nhưng nó có phải là một cách đơn giản hơn?

CẬP NHẬT

@KiranChalla hỏi trường hợp sử dụng của tôi vì vậy tôi đăng các mã còn lại là những gì. Về cơ bản tôi đang phân tích cú pháp loại phương tiện phiên bản Accept: application/vnd.app.{resource}.v{version}+json từ yêu cầu và trả lại HttpControllerDescriptor tùy thuộc vào phiên bản.

  HttpControllerDescriptor oldControllerDescriptor; 
      if (controllers.TryGetValue(controllerName, out oldControllerDescriptor)) 
      { 
       var apiVersion = GetVersionFromMediaType(request); 

       var newControllerName = String.Concat(controllerName, "V", apiVersion); 

       HttpControllerDescriptor newControllerDescriptor; 
       if (controllers.TryGetValue(newControllerName, out newControllerDescriptor)) 
       {      
        return newControllerDescriptor; 
       }    
       return oldControllerDescriptor; 
      } 
      return null; 
+2

Tôi tin rằng không có cách nào khác đơn giản rằng tôi nhận thức được. Chỉ cần fyi ... một cải tiến nhỏ, bạn có thể làm 'request.GetRouteData() GetSubRoutes()' để lấy các thuộc tính danh sách ... –

+0

Nhân tiện, bạn có thể mô tả kịch bản của bạn là gì không? Tôi tò mò muốn biết làm thế nào bạn có ý định sử dụng bộ chọn điều khiển tùy chỉnh với định tuyến thuộc tính. –

+0

@KiranChalla Cảm ơn bạn đã đề xuất. Tôi đã giải thích kịch bản của tôi và thêm mã còn lại vì vậy hãy xem và sửa tôi nếu tôi đang làm gì sai. –

Trả lời

11

Như khẳng định bởi @KiranChalla không có cách nào đơn giản hơn thì người tôi đã thực hiện, trừ các gợi ý nhỏ để sử dụng GetSubRoutes()

var attributedRoutesData = request.GetRouteData().GetSubRoutes(); 
var subRouteData = attributedRoutesData.FirstOrDefault(); 

var actions = (ReflectedHttpActionDescriptor[])subRouteData.Route.DataTokens["actions"]; 
var controllerName = actions[0].ControllerDescriptor.ControllerName; 
+0

Có bất kỳ vấn đề hiệu suất nào lớn hơn với giải pháp này không? – ainteger

+1

@ainteger Không, nó chỉ là một cách tiếp cận khác nhau để có được các dữ liệu cần thiết (tên bộ điều khiển) từ đường ống. –

+0

Đề xuất sử dụng 'GetSubRoutes()' là một gợi ý tuyệt vời. Đó là cách tiếp cận tôi đã thực hiện vì việc sử dụng 'MS_SubRoutes' phụ thuộc vào một chuỗi ký tự không có giấy tờ mà có thể dễ dàng thay đổi mà không cần cảnh báo trong tương lai. – BitMask777

Các vấn đề liên quan