Gestori messaggi HttpClient in API Web ASP.NET
Un gestore messaggi è una classe che riceve una richiesta HTTP e restituisce una risposta HTTP.
In genere, una serie di gestori di messaggi vengono concatenati insieme. Il primo gestore riceve una richiesta HTTP, esegue un'elaborazione e fornisce la richiesta al gestore successivo. A un certo punto, la risposta viene creata e torna indietro nella catena. Questo modello viene chiamato gestore di delega .
Sul lato client, la classe HttpClient usa un gestore messaggi per elaborare le richieste. Il gestore predefinito è HttpClientHandler, che invia la richiesta sulla rete e ottiene la risposta dal server. È possibile inserire gestori messaggi personalizzati nella pipeline client:
Nota
API Web ASP.NET usa anche gestori messaggi sul lato server. Per altre informazioni, vedere Gestori messaggi HTTP.
Gestori messaggi personalizzati
Per scrivere un gestore messaggi personalizzato, derivare da System.Net.Http.DelegatingHandler ed eseguire l'override del metodo SendAsync . Ecco la firma del metodo:
Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken);
Il metodo accetta httpRequestMessage come input e restituisce in modo asincrono un httpResponseMessage. Un'implementazione tipica esegue le operazioni seguenti:
- Elaborare il messaggio di richiesta.
- Chiamare
base.SendAsync
per inviare la richiesta al gestore interno. - Il gestore interno restituisce un messaggio di risposta. Questo passaggio è asincrono.
- Elaborare la risposta e restituirla al chiamante.
Nell'esempio seguente viene illustrato un gestore messaggi che aggiunge un'intestazione personalizzata alla richiesta in uscita:
class MessageHandler1 : DelegatingHandler
{
private int _count = 0;
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
System.Threading.Interlocked.Increment(ref _count);
request.Headers.Add("X-Custom-Header", _count.ToString());
return base.SendAsync(request, cancellationToken);
}
}
La chiamata a base.SendAsync
è asincrona. Se il gestore esegue qualsiasi operazione dopo questa chiamata, usare la parola chiave await per riprendere l'esecuzione dopo il completamento del metodo. Nell'esempio seguente viene illustrato un gestore che registra i codici di errore. La registrazione stessa non è molto interessante, ma l'esempio mostra come ottenere la risposta all'interno del gestore.
class LoggingHandler : DelegatingHandler
{
StreamWriter _writer;
public LoggingHandler(Stream stream)
{
_writer = new StreamWriter(stream);
}
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
if (!response.IsSuccessStatusCode)
{
_writer.WriteLine("{0}\t{1}\t{2}", request.RequestUri,
(int)response.StatusCode, response.Headers.Date);
}
return response;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_writer.Dispose();
}
base.Dispose(disposing);
}
}
Aggiunta di gestori di messaggi alla pipeline client
Per aggiungere gestori personalizzati a HttpClient, usare il metodo HttpClientFactory.Create :
HttpClient client = HttpClientFactory.Create(new Handler1(), new Handler2(), new Handler3());
I gestori di messaggi vengono chiamati nell'ordine in cui vengono passati nel metodo Create . Poiché i gestori sono annidati, il messaggio di risposta viaggia nell'altra direzione. Ovvero, l'ultimo gestore è il primo a ricevere il messaggio di risposta.