2013-08-22 18 views
16

Sto tentando di registrare le intestazioni di risposta HTTP del mio progetto API Web.Nessuna intestazione risposta in DelegatingHandler

Il progetto è sviluppato da VS2012, .NET 4.5 e ASP.NET MVC 4.

ho scritto un DelegatingHandler sottoclasse come questo:

public class LoggingHandler : DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 

     // Execute the request 
     return base.SendAsync(request, cancellationToken).ContinueWith(task => 
     { 
      var response = task.Result; 
      return response; 
     }); 
    } 
} 

Tuttavia, il problema è, posso ottenere i valori dell'intestazione dal response. response.Headers è una raccolta vuota, response.Content.Headers non contiene nient'altro che una chiave denominata Content-Type e HttpContext.Current è null.

Ho visto il codice di WebAPIContrib che utilizza la stessa logica per registrare le intestazioni, ma il loro codice non sembra funzionare neanche.

Quindi, come devo tracciare le intestazioni di risposta HTTP nel progetto API Web?

+0

Stesso problema qui. hai una soluzione? – erwineberhard

+0

No, non l'ho mai scoperto –

+0

Ho risolto il problema inviando le intestazioni di risposta al client invece di modificare il messaggio di risposta nel gestore delegante. Molto più facile anche nel mio framework javascript! – erwineberhard

risposta

0

Si deve guardare nel posto giusto:

request.Content.Headers.ContentType 

Supponendo c'è un colpo di testa Content-Type: application/json richiesta, poi il già citato tornerà "application/json".

Quindi in pratica alcune intestazioni sono associate al contenuto ed è da lì che dovresti leggerle.

Lo stesso vale per le intestazioni di risposta. A seconda del loro tipo potrebbe essere necessario estrarli dal contenuto della risposta (per le richieste che restituiscono il corpo)

response.Content.Headers.ContentType 
+0

Non otterrà ** richiesta ** intestazione? Devo registrare tutte le intestazioni di risposta, non solo ContentType ma response.Headers è vuoto – Giorgi

+0

Stessa cosa: 'response.Content.Headers' –

+0

response.Content.Headers contiene solo ContentType. Altre intestazioni (lunghezza del contenuto, cache, ecc.) Aggiunte da iis express e quindi non c'è modo di ottenerle? – Giorgi

1

Prova il codice qui sotto.

return base.SendAsync(request, cancellationToken).ContinueWith(
         task => 
         { 

          var headers = task.Result.ToString(); 
          var body = task.Result.Content.ReadAsStringAsync().Result; 

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

gestori di messaggi vengono chiamati nello stesso ordine in cui appaiono nella MessageHandlers collezione. Poiché sono nidificati, il messaggio di risposta viaggia nella direzione opposta. Cioè, l'ultimo gestore è il il primo a ricevere il messaggio di risposta.

Assicurarsi che il gestore di registrazione sia registrato all'inizio della pipeline. Preferibilmente prima

public static class WebApiConfig { 
    public static void Register(HttpConfiguration config) { 
     config.MessageHandlers.Add(new LoggingHandler(...)); 

     //...add other handlers 
     config.MessageHandlers.Add(new MessageHandler1()); 
     config.MessageHandlers.Add(new MessageHandler2()); 

     // Other code not shown... 
    } 
} 

In questo modo tutti gli altri gestori avranno la possibilità di compilare la risposta e registrare tali informazioni.

È inoltre possibile semplificare la classe utilizzando la sintassi asincrona/Attesa per rendere l'accesso alla pulitura delle risposte.

public class LoggingHandler : DelegatingHandler { 
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { 

     //...Extract and log request 
     LogRequest(request); 

     // Send the request on to the inner handler(s) and get the response 
     var response = await base.SendAsync(request, cancellationToken); 

     //...Extract details from response for logging 
     LogResponse(response); 

     return response; 
    } 

    private void LogRequest(HttpRequestMessage request) { 
     //... code removed for brevity 
    } 

    private void LogResponse(HttpResponseMessage response) { 
     //... code removed for brevity 
    } 
} 

Dovrebbe essere possibile accedere ai dettagli necessari dalla risposta prima di restituirlo.

Riferimento: HTTP Message Handlers in ASP.NET Web API

Problemi correlati