When deciding how to assign Headers to the HttpClient consider if the Headers will be the same for every request especially if the HttpClient instance is shared across all threads.
If the Headers will always be the same the DefaultRequestHeaders can be used and only needs to be assigned once.
Any changes made to
DefaultRequestHeaders will affect all threads accessing the
instance.
The example below is for .NET Core and .NET 7
// include dependencies
using System.Linq;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
// check header has not already been set
if (!_httpClient.DefaultRequestHeaders.Contains("key"))
{
_httpClient.DefaultRequestHeaders.Add("key", "value");
}
// test value exists
var headerValue = string.Empty;
if (_httpClient.DefaultRequestHeaders.Contains("key"))
{
headerValue = _httpClient.DefaultRequestHeaders.GetValues("key").First();
}
// any other configuration...
// invoke the request using GetAsync
var response = await _httpClient.GetAsync("path");
var returnValue = string.Empty;
if (response.IsSuccessStatusCode)
{
returnValue = await response.Content.ReadAsStringAsync();
}
However if the Headers are expected to change for each message, then instead setup a HttpRequestMessage instance while initializing each new request with the required values.
// include dependencies
using System.Linq;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
// use shared single instance to avoid port exhaustion in constructor etc.
_httpClient = new HttpClient();
// media-type accept header only needs to be assigned once
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// initialize request
_httpClient.BaseAddress = new Uri("https://example.com/");
var headersDictionary = new Dictionary<string, string>()
{
{"key1", "value1"},
{"key2", "value2"}
};
// create instance of HttpRequestMessage
var httpRequestMessageObject = new HttpRequestMessage(HttpMethod.Get, "relativePath");
var body = "content";
httpRequestMessageObject.Content = new StringContent(body, Encoding.UTF8, "application/json");
// check keys are not duplicated
foreach (var header in headersDictionary)
{
if (!httpRequestMessageObject.Headers.Contains(header.Key))
{
httpRequestMessageObject.Headers.Add(header.Key, header.Value);
}
}
// test value exists
var headerValue = string.Empty;
if (httpRequestMessageObject.Headers.Contains("key"))
{
headerValue = httpRequestMessageObject.Headers.GetValues("key").First();
}
// invoke the request using SendAsync
var response = await _httpClient.SendAsync(httpRequestMessageObject);
var returnValue = string.Empty;
if (response.IsSuccessStatusCode)
{
returnValue = await response.Content.ReadAsStringAsync();
}
Reference
This is demonstated further in the following Stack Overflow answers:
- https://stackoverflow.com/a/37929393/1165173
- https://stackoverflow.com/a/10679340/1165173