HttpClientHandler is the final handler in HttpClient’s outbound pipeline. It opens the network connection and sends the HTTP request, while earlier HttpMessageHandlers can adjust the request or inspect the response. section 33.2.1 section 33.5
Its lifetime matters. Disposing handlers repeatedly can contribute to socket exhaustion, while keeping one handler forever can miss DNS changes. IHttpClientFactory separates HttpClient lifetime from handler lifetime, pools handlers, and periodically replaces them. section 33.2.1 section 33.5
Use the handler through IHttpClientFactory rather than managing its lifetime directly:
- Register the factory with AddHttpClient(). section 33.2.1
- Create an HttpClient with factory.CreateClient(); the factory supplies a managed HttpClientHandler. section 33.2.1
- Configure named or typed clients when different APIs need centralized settings or an abstraction over HTTP mechanics. section 33.5
A factory-managed request
builder.Services.AddHttpClient(); app.MapGet("/", async (IHttpClientFactory factory) => { HttpClient client = factory.CreateClient(); client.BaseAddress = new Uri("https://example.com/rates/"); var response = await client.GetAsync("latest"); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); }); The application configures and uses HttpClient, while IHttpClientFactory manages the underlying handler pipeline. section 33.2.1
Figure 33.4 Each HttpClient contains a pipeline of HttpMessageHandlers. The final handler is an HttpClientHandler, which makes the connection to the remote server and sends the HTTP request. This configuration is similar to the ASP.NET Core middleware pipeline, and it allows you to make cross-cutting adjustments to outgoing requests.
The pipeline diagram shows how HttpClient passes requests through multiple handlers before HttpClientHandler connects to the remote server. section 33.2.1
