How to re-use an HttpClient instance with SendAsync

Erick McCollum | 16 Jun 2021

DISCLAIMER: The opinions expressed on this website are solely my own, and they are not associated with my employer, another person, or another organization in any way. All information on this website is provided "as is", without guarantee or warranty of any kind. Read the full disclaimer here.

When using the .NET HttpClient class, there are many different methods that allow one to send HTTP requests to specified API endpoints. Some of the most common are:

  • GetAsync
  • PostAsync
  • PutAsync
  • PatchAsync
  • DeleteAsync

The above-mentioned methods are convenient and effective to use. However, there is a down side to these methods. These methods require the programmer to set HTTP request headers on the HttpClient instance itself through the DefaultRequestHeaders properrty.

This presents a problem when attempting to re-use an HttpClient instance with multiple different API endpoints. Authentication headers will likely need to be updated for each API endpoint. The DefaultRequestHeaders property is not thread-safe. Therefore, it is not feasible to update the DefaultRequestHeaders property every time a request is made to a different API endpoint.

One solution to this problem is to use the HttpClient.SendAsync() method. This method accepts an individual HttpRequestMessage object as a parameter. This enables the programmer to set individual headers, URI, content, etc. for each individual HTTP request that is made from an HttpClient instance.

To demonstrate this, I have provided an example below. The first code snippet shows how to send an HTTP POST request using the HttpClient.PostAsync() method. The second code snippet shows how to make the same HTTP POST request using the HttpClient.SendAsync() method.

Using HttpClient.PostAsync().


    // Create Uri and POST body content.
    Uri requestUri = new Uri("https://example.com/api/");
    StringContent content = new StringContent("{ \"firstName\": \"John\", \"lastName\": \"Doe\"}");

    // Create HttpClient instance and set OAuth header.
    using HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "{OAuth token}");

    // Send HTTP POST request.
    using HttpResponseMessage response = await client.PostAsync(requestUri, content);
    

Using HttpClient.SendAsync().


    // Create Uri and POST body content.
    Uri requestUri = new Uri("https://example.com/api/");
    StringContent content = new StringContent("{ \"firstName\": \"John\", \"lastName\": \"Doe\"}");

    // Create HttpClient instance.
    using HttpClient client = new HttpClient();

    // Create HttpRequestMessage and set method, OAuth header, and content.
    using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri);
    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "{OAuth token}");
    request.Content = content;

    // Send HTTP POST request.
    using HttpResponseMessage response = await client.SendAsync(request);
    

The above code snippets may be found in my GitHub repository at the following link: code-samples/dotnet/HttpClient-SendAsync.

Additional resources.