2012-10-20 12 views

Odpowiedz

15

Nie, ponieważ moduły obsługi komunikatów działają na surowym HttpRequestMessage lub surowym HttpResponseMessage (w przypadku kontynuacji). Tak naprawdę, nie ma koncepcji "bieżącego kontrolera wykonującego" z DelegatingHandlers, ponieważ procedury obsługi komunikatów zostaną wywołane przed wysłaniem żądania do kontrolera lub (ponownie w przypadku kontynuacji) po tym, jak kontroler zwróci odpowiedź.

Jednak to naprawdę zależy od tego, co próbujesz zrobić.

Jeśli chcesz wiedzieć, do którego kontrolera zostanie wysłane żądanie, możesz ręcznie wywołać mechanizm, który będzie wewnętrznie wybierać kontrolery.

public class MyHandler : DelegatingHandler 
{ 
    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) 
    { 
     var config = GlobalConfiguration.Configuration; 
     var controllerSelector = new DefaultHttpControllerSelector(config); 

     // descriptor here will contain information about the controller to which the request will be routed. If it's null (i.e. controller not found), it will throw an exception 
     var descriptor = controllerSelector.SelectController(request); 

     // continue 
     return base.SendAsync(request, cancellationToken); 
    } 
} 
+0

Dzięki, mam procedurę walidacji i byłoby miło, aby móc sprawdzić typ kontrolera, aby zobaczyć, czy ma ona atrybut niestandardowy zdefiniowany, więc mogę tego uniknąć rutyny weryfikacji. Powinno to umożliwić. –

+0

świetnie. tak, możesz to łatwo zrobić po pobraniu instancji HttpControllerDescriptor –

+0

@FilipW Czy istnieje "ładny" sposób na zrobienie tego bez wyrzucania wyjątku? w kodzie źródłowym wywołanie 'SelectController' ostatecznie wywołuje' this._controllerInfoCache.Value.TryGetValue (controllerName, out controllerDescriptor) 'jednak' _controllerInfoCache' nie jest publicznie dostępny w żaden sposób – wal

0

Rozszerzanie rozwiązania @GalacticBoy, byłoby lepiej użyć

public class MyHandler : DelegatingHandler 
{ 
    private static IHttpControllerSelector _controllerSelector = null; 

    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) 
    { 
     if (_controllerSelector == null) 
     { 
      var config = request.GetConfiguration(); 
      _controllerSelector = config.Services.GetService(typeof(IHttpControllerSelector)) as IHttpControllerSelector; 
     } 

     try 
     { 
      // descriptor here will contain information about the controller to which the request will be routed. If it's null (i.e. controller not found), it will throw an exception 
      var descriptor = _controllerSelector.SelectController(request); 


     } 
     catch 
     { 
      // controller not found 
     } 

     // continue 
     return base.SendAsync(request, cancellationToken); 
    } 
} 
0

W zależności od tego, co robisz z informacjami Może twój grzywny z uzyskanie informacji po żądanie jest wykonywane. Na przykład logowanie wykonanego kontrolera/akcji.

using System; 
using System.Net.Http; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Web; 

namespace Example 
{ 
    public class SampleHandler : DelegatingHandler 
    { 
     protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
     { 
      return base.SendAsync(request, cancellationToken) 
         .ContinueWith(task => 
         { 
          HttpResponseMessage response = task.Result; 

          string actionName = request.GetActionDescriptor().ActionName; 
          string controllerName = request.GetActionDescriptor().ControllerDescriptor.ControllerName; 

          // log action/controller or do something else 

          return response; 
         }, cancellationToken); 
     } 
    } 
} 
Powiązane problemy