Programy obsługi komunikatów HttpClient w internetowym interfejsie API ASP.NET

Procedura obsługi komunikatów to klasa, która odbiera żądanie HTTP i zwraca odpowiedź HTTP.

Zazwyczaj szereg procedur obsługi komunikatów jest w łańcuchu. Pierwsza procedura obsługi odbiera żądanie HTTP, wykonuje pewne przetwarzanie i przekazuje żądanie następnej procedurze obsługi. W pewnym momencie odpowiedź jest tworzona i tworzy kopię zapasową łańcucha. Ten wzorzec jest nazywany procedurą obsługi delegowania .

Diagram procedur obsługi komunikatów w łańcuchu, ilustrujący proces odbierania żądania T P H T I zwracanie odpowiedzi H T T P.

Po stronie klienta klasa HttpClient używa programu obsługi komunikatów do przetwarzania żądań. Domyślna procedura obsługi to HttpClientHandler, która wysyła żądanie za pośrednictwem sieci i pobiera odpowiedź z serwera. Niestandardowe programy obsługi komunikatów można wstawić do potoku klienta:

Diagram procesu wstawiania niestandardowych programów obsługi komunikatów do potoku klienta. Pokazuje h t t p Klasa klienta, która używa programu obsługi komunikatów do przetwarzania żądań.

Uwaga

ASP.NET internetowy interfejs API używa również programów obsługi komunikatów po stronie serwera. Aby uzyskać więcej informacji, zobacz Programy obsługi komunikatów HTTP.

Niestandardowe programy obsługi komunikatów

Aby napisać niestandardową procedurę obsługi komunikatów, należy utworzyć metodę System.Net.Http.DelegatingHandler i zastąpić metodę SendAsync . W tym miejscu znajduje się sygnatura metody:

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

Metoda przyjmuje httpRequestMessage jako dane wejściowe i asynchronicznie zwraca komunikat HttpResponseMessage. Typowa implementacja wykonuje następujące czynności:

  1. Przetwórz komunikat żądania.
  2. Wywołaj metodę base.SendAsync , aby wysłać żądanie do procedury obsługi wewnętrznej.
  3. Program obsługi wewnętrznej zwraca komunikat odpowiedzi. (Ten krok jest asynchroniczny).
  4. Przetwórz odpowiedź i zwróć ją do elementu wywołującego.

Poniższy przykład przedstawia procedurę obsługi komunikatów, która dodaje niestandardowy nagłówek do żądania wychodzącego:

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

Wywołanie metody base.SendAsync jest asynchroniczne. Jeśli program obsługi wykonuje jakąkolwiek pracę po tym wywołaniu, użyj słowa kluczowego await , aby wznowić wykonywanie po zakończeniu działania metody. Poniższy przykład przedstawia procedurę obsługi, która rejestruje kody błędów. Samo rejestrowanie nie jest bardzo interesujące, ale w przykładzie pokazano, jak uzyskać odpowiedź wewnątrz procedury obsługi.

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

Dodawanie programów obsługi komunikatów do potoku klienta

Aby dodać niestandardowe programy obsługi do obiektu HttpClient, użyj metody HttpClientFactory.Create :

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

Programy obsługi komunikatów są wywoływane w kolejności przekazywania ich do metody Create . Ponieważ programy obsługi są zagnieżdżone, komunikat odpowiedzi jest przesyłany w innym kierunku. Oznacza to, że ostatnia procedura obsługi jest pierwszą, aby uzyskać komunikat odpowiedzi.