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.

To download the source code for this article, you can visit our GitHub repository.

Let’s start.

What Is a User-Agent Header?

Before we learn to set User-Agent on HttpClient, let’s understand the basics.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

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.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!