In this article, we will learn about the User-Agent header used while making HTTP calls. Then, we will understand how to set the default User-Agent on an HttpClient.
Let’s start.
What Is a User-Agent Header?
Before we learn to set User-Agent
on HttpClient
, let’s understand the basics.
The user agent is a set of strings sent by web applications or API clients while making HTTP calls to the backend webservers. We generally specify it in the format:
User-Agent: Product/ProductVersion <comments>
Let’s understand this.
The header value contains three distinct pieces of information:
- Product: Information about the product making the HTTP calls
- Product Version: The version of the product
- Comments: Zero or more comments that provide more detail about the product
For example, let’s see how the header looks for version 1.1 of a product called CodeMazeDesktopApp:
User-Agent: CodeMazeDesktopApp/1.1
Moreover, we can use User-Agent
values:
- To check and limit access to our APIs to only certain products or browsers
- To check and tailor the user experience of our web applications based on the type of device making the HTTP call
- To analyze the user engagement behaviors based on the device used to access our web applications or APIs
With this basic knowledge, let’s explore how we can set the User-Agent
while making HTTP calls.
How to Set User-Agent on HTTP Request Message?
Let’s look at a simple way to set the User-Agent
header for individual HTTP requests that we make with HttpClient
:
public class Program { public static void Main(string[] args) { var userAgentValue = SetUserAgentOnHttpRequestMessage("CodeMazeDesktopApp/1.1"); } public static string SetUserAgentOnHttpRequestMessage(string userAgentValue) { var httpRequestMessage = new HttpRequestMessage(); httpRequestMessage.Headers.Add("User-Agent", userAgentValue); return httpRequestMessage.Headers.UserAgent.ToString(); } }
First, in our SetUserAgentOnHttpRequestMessage()
method, we initialize an instance of the HttpRequestMessage
. Next, we use the Add()
method of the Headers
property to set the value of the user agent. Finally, we return the string value of the UserAgent
property.
When we test this method from the Main()
method of our console app, it will return us the result:
CodeMazeDesktopApp/1.1
With this done, let’s see how we can set the header cleanly using the inbuilt capabilities provided by ASP.NET Core.
Setting the User-Agent Cleanly
We can use the ProductHeaderValue
and ProductInfoHeaderValue
classes available in the System.Net.Http.Headers
namespace to set the User-Agent
header cleanly.
Accordingly, let’s refactor our code:
public class Program { public static void Main(string[] args) { var userAgentValue = SetUserAgentOnHttpRequestMessage("CodeMazeDesktopApp", "1.1"); } public static string SetUserAgentOnHttpRequestMessage(string productName, string productVersion) { var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "/users/1234"); var productHeaderValue = new ProductHeaderValue(name: productName, version: productVersion); var productInfoHeaderValue = new ProductInfoHeaderValue(product: productHeaderValue); httpRequestMessage.Headers.UserAgent.Add(productInfoHeaderValue); return httpRequestMessage.Headers.UserAgent.ToString(); } }
First, we initialize an instance of ProductHeaderValue
by providing the product name and version to its constructor. Next, we initialize an instance of the ProductInfoHeaderValue
class. Then, we add the ProductInfoHeaderValue
instance to the UserAgent
collection on the Headers
property using the Add()
method. Finally, we return the string value of the UserAgent
property.
When we test this method from the Main()
method of our console app, it will return us the result:
CodeMazeDesktopApp/1.1
We have made our code cleaner now. However, in this approach, our code sets the user agent value every time the HttpRequestMessage
instance is created.
Let’s now see how to set a default User-Agent
on an HttpClient
.
How to Set Default User-Agent on an Httpclient?
As a best practice. we should always use the HttpClientFactory
to implement the HttpClient
in ASP.NET Core application. To use the HttpClientFactory
, we must first install the Microsoft.Extensions.Http
NuGet package in our application:
PM> Install-Package Microsoft.Extensions.Http
With the package now installed, let’s add the IHttpClientFactory
service to our service collection:
public static IHost BuildHost() { var builder = new HostBuilder() .ConfigureServices(services => { services.AddHttpClient("CodeMazeHttpClient", client => { var productHeaderValue = new ProductHeaderValue(name: "CodeMazeDesktopApp", version: "1.1"); var productInfoHeaderValue = new ProductInfoHeaderValue(productHeaderValue); client.DefaultRequestHeaders.UserAgent.Add(productInfoHeaderValue); }); }); return builder.Build(); }
We begin by creating a builder with HostBuilder
. This builder is the utility to build the container that stores all the services that our app needs. Next, we add the collection of important services using the ConfigureServices()
method. We add the IHttpClientFactory
and the related services to the service collection using the AddHttpClient()
method. Here, we are adding a HttpClient
named CodeMazeHttpClient. Next, we use the clean method we discussed in Setting the User-Agent Cleanly to set the user agent. Furthermore, we add the default user agent using the Add()
method on the UserAgent
property on the DefaultRequestHeaders
. Finally, we return the host by using the Build()
command on the builder we just configured.
With the host now configured, let’s read the user agent of the HttpClient
:
public static string GetDefaultAgentOnHttpClient(IHttpClientFactory httpClientFactory) { var httpClient = httpClientFactory.CreateClient("CodeMazeHttpClient"); return httpClient.DefaultRequestHeaders.UserAgent.ToString(); }
We create an instance of HttpClient
named CodeMazeHttpClient using the CreateClient()
method on the IHttpClientFactory
. Finally, we return the string value of the UserAgent
property.
Next, let’s invoke this method from the Main()
method of our console app:
public static void Main(string[] args) { var host = BuildHost(); var httpClientFactory = host.Services.GetService<IHttpClientFactory>(); var defaultUserAgentOnHttpClient = GetDefaultAgentOnHttpClient(httpClientFactory); }
We begin with building the host using the BuildHost()
method we created earlier. Next, we request an instance of the IHttpClientFactory
using the GetService<IHttpClientFactory>()
method. Finally, we execute the GetDefaultAgentOnHttpClient()
method and we get the result:
CodeMazeDesktopApp/1.1
Using this approach, we set the user agent only once in the HttpClient
instance’s lifetime.
In our example, we used a simple version of HostBuilder
and IHttpClientFactory
to create HttpClient
. But, in real-world implementations, we should follow the best practices mentioned in our Using HttpClientFactory in ASP.NET Core Applications article.
Conclusion
To sum it up, in this article, we learned about the User-Agent header property and some of its uses. Next, we learned how to set the User-Agent header cleanly on the HttpRequestMessage object. Finally, we learned how to set a default User-Agent value which can be used for the entire lifetime of an HttpClient.