2012-08-15 14 views
21

Obecnie używam kilku modułów obsługi delegacji (klas wywodzących się z DelegatingHandler) do pracy nad żądaniem przed wysłaniem, na przykład na sprawdzanie poprawności podpisu itp. To wszystko jest bardzo ładne, ponieważ nie muszą duplikować sprawdzanie poprawności podpisu dla wszystkich połączeń (na przykład).DelegowanieHandler do odpowiedzi w WebApi

Chciałbym użyć tej samej zasady w odniesieniu do odpowiedzi z tego samego żądania internetowego. Czy jest coś podobnego do DelegatingHandler dla odpowiedzi? Sposób na złapanie odpowiedzi, zanim wróci do metody?

Dodatkowe informacje: Wołam API internetową korzystając HttpClient.PutAsync(...)

Odpowiedz

37

Tak. Możesz to zrobić w zadaniu kontynuacji.

Wyjaśnię to here.

Na przykład ten kod (z powyższego bloga) śledzi identyfikator URI żądania i dodaje fałszywy nagłówek do odpowiedzi.

public class DummyHandler : DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     // work on the request 
     Trace.WriteLine(request.RequestUri.ToString()); 

     return base.SendAsync(request, cancellationToken) 
      .ContinueWith(task => 
      { 
       // work on the response 
       var response = task.Result; 
       response.Headers.Add("X-Dummy-Header", Guid.NewGuid().ToString()); 
       return response; 
      }); 
    } 
} 
+0

Ach, teraz rozumiem przykłady używając ContinueWith. Działa to świetnie. Dziękuję (i przepraszam za powolną odpowiedź) – Halvard

+0

Jak byś się przeczytał tutaj? Próbuję go odczytać, ale generuje wyjątek wyjątku. –

+0

@RossJones To dziwne ... czy możesz wysłać repro? – Aliostad

13

Oto przykład przechwytywania żądania i odpowiedzi. zastąpiona metoda SendAsync służy do przechwytywania pierwotnego żądania, natomiast metoda zwana ResponseHandler służy do przechwytywania odpowiedzi.

Przykład uchwycić pierwotne żądanie i odpowiedź

using System.Net.Http; 
using System.Threading.Tasks; 
namespace webAPI_Test 
{ 
    public class MessageInterceptor : DelegatingHandler 
    { 
     protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) 
     { 
      // CATCH THE REQUEST BEFORE SENDING TO THE ROUTING HANDLER 
      var headers = request.ToString(); 
      var body = request.Content.ReadAsStringAsync().Result; 
      var fullRequest = headers + "\n" + body; 

      // SETUP A CALLBACK FOR CATCHING THE RESPONSE - AFTER ROUTING HANDLER, AND AFTER CONTROLLER ACTIVITY 
      return base.SendAsync(request, cancellationToken).ContinueWith(
         task => 
         { 
          // GET THE COPY OF THE TASK, AND PASS TO A CUSTOM ROUTINE 
          ResponseHandler(task); 

          // RETURN THE ORIGINAL RESULT 
          var response = task.Result; 
          return response; 
         } 
      ); 
     } 

     public void ResponseHandler(Task<HttpResponseMessage> task) 
     { 
      var headers = task.Result.ToString(); 
      var body = task.Result.Content.ReadAsStringAsync().Result; 

      var fullResponse = headers + "\n" + body; 
     } 
    } 
} 

celu wykorzystania tej metody w klasie musi być zidentyfikowane i zarejestrowana MessageHandler. I dodaje następujący wiersz do mojego pliku Global.asax ...

Przykład: jak zarejestrować nową klasę MessageInterceptor

GlobalConfiguration.Configuration.MessageHandlers.Add(new MessageInterceptor()); 

Oto mój pełny plik Global.asax. Zauważ, jak MessageInterceptor odwołuje ...

Pełna wersja Global.asax pokazujący integrację MessageInterceptor

using System.Web.Http; 
using System.Web.Mvc; 
using System.Web.Optimization; 
using System.Web.Routing; 
namespace webAPI_Test 
{ 
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801 

    public class WebApiApplication : System.Web.HttpApplication 
    { 
     protected void Application_Start() 
     { 
      AreaRegistration.RegisterAllAreas(); 

      WebApiConfig.Register(GlobalConfiguration.Configuration); 
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
      RouteConfig.RegisterRoutes(RouteTable.Routes); 
      BundleConfig.RegisterBundles(BundleTable.Bundles); 

      GlobalConfiguration.Configuration.MessageHandlers.Add(new MessageInterceptor()); 
     } 
    } 
} 
Powiązane problemy