2012-09-11 16 views
13

başarıyla bir Web API rota ala için global.asax.cs içindeki (IRouteHandler kaynaklanan) özel bir rota işleyicisi kaydetmek mümkün değilim: AncakÖzel rota işleyicileri

 routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "{client}/api/1.0/{controller}/{action}/{id}", 
      defaults: new{id = UrlParameter.Optional} 
     ).RouteHandler = new SingleActionAPIRouteHandler(); 

ben yapabilirsiniz HttpConfiguration.Routes.MapRoute çağrısı döndüğümde, IHttpRoute döndürülen bir işleyiciyi ayarlayamadığımda, tümleştirme sınaması için API için bir bellek ana bilgisayarını kurmaya çalışırken bunu yapmak için bir yol bulamıyor.

Bunu farklı şekilde yapmalı mıyım (örneğin özel bir HttpControllerSelector kullanarak)? Her iki durumda da aynı şekilde yapmak isterim.

sayesinde Matt

DÜZENLEME:

public class CustomHttpControllerDispatcher : HttpControllerDispatcher 
{ 
    public CustomHttpControllerDispatcher(HttpConfiguration configuration) : base(configuration) 
    { 
    } 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     // My stuff here 

     return base.SendAsync(request, cancellationToken); 
    } 
} 

cevap

13

Siz: Ben temelde aşağıda tavsiye takip ediyordu yapıyorum ama şöyle basitçe HttpControllerDispatcher sınıfını geçersiz kılma sona erdi Peki

çok doğru Self host, IHttpRoute değerini döndürür ve HttpMessageHandler parametresini parametre olarak alır. Bir rota işleyicisinin özgüllüğü için dahili bir yol yok gibi görünüyor.

Güncelleme:

Neredeyse kesinlikle kullanarak gitmek var olmalıdır biraz daha net olmak gerekirse bir HttpControllerSelector ve özel bir yumuşatma ... olmanın örneği uygulamak. HttpControllerSelector ne olursa sebepten dolayı gereksinimleri için yeterli görülmüyorsa ne izler deney biraz olan http://netmvc.blogspot.co.uk/

...

Ama MapHttpRoute gördüğünüz gibi HttpMessageHandler için bir aşırı var sen de Bunu deneyebilirsiniz ... if the handler is NULL then it defaults to IHttpController ama kendi kendinize uygulayabilirsiniz ve bunu doğru denetleyiciye yönlendirmek için kullanabilirsiniz ... MVC çerçevesi [HttpControllerDispatcher]here'u kullanıyor görünmektedir, bu yüzden bazı kodları ödünç almak için kendi denetleyicinizi/rota seçim kodunuzu buraya koyabilirsiniz Ayrıca - rotaya ve seçiciye erişiminiz vardır ve bunu kendi içinde ve dışında değiştirebilirsiniz.

Bu CustomHttpControllerDispatcher kodu yalnızca ... satır arayın

// Denetleyiciniz

PICK Ve belki bununla ilgili bir oyun var İÇİN ÖZEL BURAYA ŞEYLER YAPMAK DEMO içindir ...

Örnek rota:

 config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/{controller}/{id}", 
      defaults: new { id = RouteParameter.Optional }, 
      constraints: null, 
      handler: new CustomHttpControllerDispatcher(config) 
     ); 

Örnek CustomHttpControllerDispatcher:

public class CustomHttpControllerDispatcher : HttpMessageHandler 
{ 
     private IHttpControllerSelector _controllerSelector; 
     private readonly HttpConfiguration _configuration; 

     public CustomHttpControllerDispatcher(HttpConfiguration configuration) 
     { 
      _configuration = configuration; 
     } 

     public HttpConfiguration Configuration 
     { 
      get { return _configuration; } 
     } 

     private IHttpControllerSelector ControllerSelector 
     { 
      get 
      { 
       if (_controllerSelector == null) 
       { 
        _controllerSelector = _configuration.Services.GetHttpControllerSelector(); 
       } 
       return _controllerSelector; 
      } 
     } 

     protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
     { 
       return SendAsyncInternal(request, cancellationToken); 
     } 

     private Task<HttpResponseMessage> SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken) 
     { 

      IHttpRouteData routeData = request.GetRouteData(); 
      Contract.Assert(routeData != null); 

      //DO SOMETHING CUSTOM HERE TO PICK YOUR CONTROLLER 
      HttpControllerDescriptor httpControllerDescriptor = ControllerSelector.SelectController(request); 
      IHttpController httpController = httpControllerDescriptor.CreateController(request); 

      // Create context 
      HttpControllerContext controllerContext = new HttpControllerContext(_configuration, routeData, request); 
      controllerContext.Controller = httpController; 
      controllerContext.ControllerDescriptor = httpControllerDescriptor; 

      return httpController.ExecuteAsync(controllerContext, cancellationToken); 
     } 
} 
çok Mark, WebAPI çerçevenin iç yapısına oldukça yeni olarak kabul edeceğiz
+0

sayesinde, bu yaklaşım için özel IHttpControllerSelector tedarik daha iyidir neden açıklayabilir yapılandırma?Varsayılan HttpControllerDispatcher, yapmak istediğim işin bakımı için konfigürasyonda tanımlanan ControllerSelector'ı kullanıyor gibi görünüyor. – mattcole

+0

@mattcole Biraz daha net olmalıydım - Doğru olduğunuzu onaylamak istedim ve şüphelendiğim gibi (zaten yaptığınız gibi) özel bir HttpControllerSelector'a sahip olmanız gerektiğini http://netmvc.blogspot.co.uk/yaptığınız her şeyin bir denetleyiciye yönlendirilmesidir. Ben sadece siz belki de kontrolörlerin seçiminden daha fazlasını yapıyorsunuzdur ve belki de kontrolörden başka başka işleyicileri kullanmak istemişsinizdir ... CustomHttpControllerDispatcher fikri biraz daha açık bir oyun ve deneyimdi ... daha açık olmamak için üzgünüm. –

+0

Sorun yok Mark, sonunda, sadece SendAsync yöntemini aştığım routevallerde sadece bazı değerleri değiştirdiğim için, önerdiğim şeyin bir versiyonuna gittim, işimi yaptım ve sonra boru hattının yoluna devam etmesine izin verdim. – mattcole