DelegatingHandler – jak rozszerzyć działanie klienta http w c#

Udostępnij

Wprowadzenie

HttpClient może być rozszerzony o dodatkową logikę za pomocą DelegatingHandler. Jest to klasa bazowa, która pozwala nam dodać dodatkowe zachowania bez konieczności modyfikowania oryginalnego kodu przetwarzającego żądania. Moim zdaniem, im więcej elastyczności dostajemy nie modyfikując kodu naszej aplikacji, tym lepiej!

Przykłady użycia

DelegatingHandler jest klasą abstrakcyjną, która udostępnia metodę SendAsync. Dzięki temu mamy kontrolę nad HttpClient, ponieważ możemy dodać kod przed wysłaniem zapytania lub po otrzymaniu odpowiedzi. To daje nam spore możliwości — na przykład możemy dodać jakieś dodatkowe nagłówki http.

public class AddClientIdHeaderHandler : DelegatingHandler
{
    public const string ClientId = "a12b34c5-d678-90ef-gh12-3456789ijkl";

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Headers.Add("x-client-id", ClientId);

        return base.SendAsync(request, cancellationToken);
    }
}

Korzystając z IServiceCollection, podczas rejestracji HttpClient możemy skorzystać z metody AddHttpMessageHandler, która pozwala dodać nasz własny handler. Warto pamiętać, że nasza nowa klasa handlera również musi zostać zarejestrowana w kontenerze DI!

builder.Services.AddTransient<AddClientIdHeaderHandler>();

builder.Services.AddHttpClient<MyClient>(x =>
{
    x.BaseAddress = new Uri("http://myapi.com");
}).AddHttpMessageHandler<AddClientIdHeaderHandler>();

Dodatkowo jeszcze możemy chainować nasze handlery, rejestrując kilka z nich. Pamiętajcie zawsze żeby wasz handler wywołał metodę bazową, żeby nie zatrzymać procesowania!

builder.Services.AddHttpClient<MyClient>(x =>
{
    x.BaseAddress = new Uri("http://myapi.com");
})
.AddHttpMessageHandler<AddClientIdHeaderHandler>()
.AddHttpMessageHandler<CustomHandler>();

Przykłady zastosowań to, na przykład właśnie dodawanie nagłówków statycznych. Korzystamy z kontenera DI, dzięki temu możemy również wyciągać dane korzystając z IHttpContextAccessor. Możemy też stworzyć handler który będzie logował dane korzystająć z ILogger.

Czytaj również  Zmiany w c# na przestrzeni lat - part 2
Scroll to Top