Search code examples
c#dependency-injectionhttpclient

How do you inject the HttpMessageHandler into the HttpClient object using ASP.NET Core dependency injection?


Without using ASP.NET Core's DI, you can put a ClientHandler which contains a cookie container into the HttpClient object using its constructor, something similar to this:

        var cookieContainer = new CookieContainer();
        var handler = new HttpClientHandler() { CookieContainer = cookieContainer };

        var client = new HttpClient(handler)
            {
                BaseAddress = new Uri(uri),
                Timeout = TimeSpan.FromMinutes(5)
            };

but when you try to use DI, you don't have the opportunity to call the HttpClient's constructor and pass the handler in. I tried this next line of code:

        services.AddHttpClient<HttpClient>(client =>
            {
                client.BaseAddress = new Uri(uri);
                client.Timeout = TimeSpan.FromSeconds(5);
            });

but indeed, it doesn't have a cookie container when you get an instance.


Solution

  • You can do this by adding a named client instead (which have additional configuration options). We'll simply create a new HttpClientHandler with a cookie container:

    services.AddHttpClient("myServiceClient")
        .ConfigureHttpClient(client =>
        {
            client.BaseAddress = new Uri(uri);
            client.Timeout = TimeSpan.FromSeconds(5);
        })
        .ConfigurePrimaryHttpMessageHandler(
            () => new HttpClientHandler() { CookieContainer = new CookieContainer() }
        );
    

    And then you can resolve the client like so:

    public class MyService(IHttpClientFactory clientFactory)
    {
        // "myServiceClient" should probably be replaced in both places with a 
        // constant (const) string value to avoid magic strings
        var httpClient = clientFactory.CreateClient("myServiceClient");
    }
    

    It's also possible to bind the HttpClient to the service by supplying a generic parameter to AddHttpClient:

    services.AddHttpClient<MyService>("myServiceClient") // or services.AddHttpClient<MyServiceInterface, MyServiceImplementation>("myServiceClient")
        .ConfigureHttpClient(client =>
        {
            client.BaseAddress = new Uri(uri);
            client.Timeout = TimeSpan.FromSeconds(5);
        })
        .ConfigurePrimaryHttpMessageHandler(
            () => new HttpClientHandler() { CookieContainer = new CookieContainer() }
        );
    

    And then you can simply accept an HttpClient in your service:

    public class MyService
    {
        public MyService(HttpClient httpClient)
        {
        }
    }