Obslužné rutiny zpráv HttpClient ve webovém rozhraní 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 přijme požadavek HTTP, provede určité zpracování a předá požadavek další obslužné rutině. V určitém okamžiku se vytvoří odpověď a vrátí se zpět do řetězu. Tento vzor se nazývá obslužná rutina delegování .

Diagram zřetězených obslužných rutin zpráv znázorňující 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 kanálu klienta můžete vložit vlastní obslužné rutiny zpráv:

Diagram procesu pro vložení vlastních obslužných rutin zpráv do kanálu klienta Zobrazuje h t t p klientskou třídu, 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, odvodit z System.Net.Http.DelegatingHandler a přepsat Metodu SendAsync . Tady je podpis této metody:

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

Metoda přijímá HttpRequestMessage jako vstup a asynchronně vrací HttpResponseMessage. Typická implementace provede následující:

  1. Zpracujte zprávu požadavku.
  2. Voláním base.SendAsync odešlete požadavek do vnitřní obslužné rutiny.
  3. Vnitřní obslužná rutina vrátí zprávu odpovědi. (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á do odchozího požadavku přidá vlastní hlavičku:

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í base.SendAsync je asynchronní. Pokud obslužná rutina provede nějakou práci po tomto volání, 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í příliš 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í obslužných rutin 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í, v jakém je předáte do metody Create . Vzhledem k tomu, že obslužné rutiny jsou vnořené, zpráva odpovědi se pohybuje v opačném směru. To znamená, že poslední obslužná rutina je první, která získá zprávu odpovědi.