Obslužné moduly zpráv HttpClient ve Web API ASP.NET

Obslužná rutina zprávy je třída, která přijímá požadavek HTTP a vrací odpověď HTTP.

Obvykle je řada obslužných rutin zpráv zřetězených dohromady. První obslužná rutina obdrží požadavek HTTP, provede zpracování a poskytne požadavek další obslužné rutině. V určitém okamžiku se vytvoří odpověď a putuje zpět nahoru po řetězci. Tento vzor se nazývá delegovaný obslužný modul.

Diagram obslužných rutin zpráv zřetězených dohromady, který znázorňuje proces přijetí požadavku H T T P a vrácení odpovědi H T T P

Na straně klienta třída HttpClient používá obslužnou rutinu zprávy ke zpracování požadavků. Výchozí obslužná rutina je HttpClientHandler, která odešle požadavek přes síť a získá odpověď ze serveru. Do zpracovatelského řetězce klienta můžete vložit vlastní obslužné moduly zpráv:

Diagram procesu vložení vlastních obslužných rutin zpráv do kanálu klienta Zobrazuje h t t p Client třídy, která ke zpracování požadavků používá obslužnou rutinu zprávy.

Poznámka:

ASP.NET webové rozhraní API také používá obslužné rutiny zpráv na straně serveru. Další informace najdete v tématu Obslužné rutiny zpráv HTTP.

Vlastní obslužné rutiny zpráv

Chcete-li napsat vlastní obslužnou rutinu zprávy, odvoďte ji z System.Net.Http.DelegatingHandler a přepište metodu SendAsync. Tady je podpis metody:

Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request, CancellationToken cancellationToken);

Metoda vezme HttpRequestMessage jako vstup asynchronně vrátí HttpResponseMessage. Typická implementace provede následující:

  1. Zpracujte zprávu požadavku.
  2. Zavolejte base.SendAsync k odeslání požadavku do vnitřního zpracovatele.
  3. Vnitřní obsluha vrátí odpověď. (Tento krok je asynchronní.)
  4. Zpracujte odpověď a vraťte ji volajícímu.

Následující příklad ukazuje obslužnou rutinu zprávy, která přidá vlastní hlavičku do odchozího požadavku:

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);
    }
}

Volání na base.SendAsync je asynchronní. Pokud obslužná rutina po tomto volání funguje, použijte klíčové slovo await k obnovení provádění po dokončení metody. Následující příklad ukazuje obslužnou rutinu, která protokoluje kódy chyb. Samotné protokolování není velmi zajímavé, ale příklad ukazuje, jak získat odpověď uvnitř obslužné rutiny.

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);
    }
}

Přidání zpracovatelů zpráv do kanálu klienta

Pokud chcete do HttpClient přidat vlastní obslužné rutiny, použijte metodu HttpClientFactory.Create :

HttpClient client = HttpClientFactory.Create(new Handler1(), new Handler2(), new Handler3());

Obslužné rutiny zpráv se volají v pořadí, ve kterém je předáváte do metody Create. Protože obslužné rutiny jsou vnořené, zpráva odpovědi cestuje v opačném směru. To znamená, že poslední obslužná rutina je první, která obdrží odpověď.