avatarCan Sener

Summary

The provided context outlines the process of customizing HTTP clients in .NET Core applications using HttpClientFactory for improved performance and reliability.

Abstract

The article discusses the significance of effectively managing HTTP clients in .NET Core applications through the use of HttpClientFactory. It explains how to set up HttpClientFactory by adding it to the application's services and demonstrates how to extend it with custom configurations using an extension method. The customization includes setting the client's base address, default request headers, timeout, and configuring the HttpClientHandler for certificate management, SSL protocols, and decompression. The article also provides examples of a settings class and the HttpClientHandlerHelper class, which are used to manage application-specific configurations and handle certificates, respectively. The conclusion emphasizes the benefits of using HttpClientFactory with custom configurations to create robust, resilient, and efficient HTTP clients tailored to the unique requirements of .NET Core applications.

Opinions

  • The author suggests that centralized configuration and management of HTTP clients through HttpClientFactory lead to optimal performance and reliability.
  • Custom configurations are presented as a means to tailor HTTP clients to the specific needs of an application, enhancing flexibility and scenario handling.
  • The use of a custom extension method, AddHttpClients, is recommended for fine-tuned configuration of HTTP clients.
  • The importance of handling certificates, SSL protocols, and decompression through the HttpClientHandler is highlighted as a critical component in customizing HTTP client behavior.
  • The article implies that developers should integrate these practices into their projects while emphasizing the importance of fine-tuning configurations to match the application's unique requirements.

Customized HTTP Clients in .NET Core with HttpClientFactory

In the realm of modern .NET Core applications, the efficient management of HTTP clients is pivotal for achieving optimal performance and reliability. Enter HttpClientFactory, a feature that simplifies this process, offering a flexible and structured approach. This article will delve into the intricacies of constructing robust HTTP clients in .NET Core using HttpClientFactory along with custom configurations.

Setting Up HttpClientFactory

To kickstart the process, harness the power of HttpClientFactory by adding it to your application's services. Within your startup code, include the following line:

services.AddHttpClients();

This lays the foundation for centralized configuration and management of HTTP clients.

Extending Services with Custom HttpClient Configuration

Tailoring HTTP client configurations to meet specific requirements is achieved through a custom extension method. In the example below, the AddHttpClients extension method is introduced:

public static class HttpClientExtensions
{
    public static void AddHttpClients(this IServiceCollection services)
    {
        services
            .AddHttpClient("ApiClient", (provider, client) => {
                var settings = provider.GetRequiredService<ServiceSettings>();
                client.BaseAddress = new Uri(settings.BaseUrl);
                client.DefaultRequestHeaders.Add("Accept", MediaTypeNames.Application.Json);
                client.Timeout = TimeSpan.FromMilliseconds(settings.HttpTimeoutInMilliseconds);
            })
            .SetHandlerLifetime(System.Threading.Timeout.InfiniteTimeSpan)
            .ConfigurePrimaryHttpMessageHandler(provider => {
                var settings = provider.GetRequiredService<ServiceSettings>();
                return HttpClientHandlerHelper.ConfigureHttpClientHandler(settings.CertificateThumbprintOrSubjectName);
            })
    }
}

This extension method facilitates fine-tuned configuration of HTTP clients based on the specific needs of your application.

Our settings class and appsettings accordingly:

public class ServiceSettings : ISettings
{
    public string BaseUrl { get; set; }

    public string CertificateThumbprintOrSubjectName { get; set; }

    public int HttpTimeoutInMilliseconds { get; set; }

}

  "ServiceSettings": {
    "BaseUrl": "https://serviceUrl:9191/", //change accordingly with your url
    "CertificateThumbprintOrSubjectName": "testCertificate", //change accordingly if using any certificate
    "HttpTimeoutInMilliseconds": 1000
  },

HttpClientHandler Configuration

A critical component in customizing the behavior of HTTP clients is the HttpClientHandler. The HttpClientHandlerHelper class provides the ConfigureHttpClientHandler method, which handles certificates, SSL protocols, and decompression:

public static class HttpClientHandlerHelper
{
    public static HttpClientHandler CConfigureHttpClientHandler(string certificateThumbprintOrSubjectName)
    {
        try
        {
            var certificate = GetCertificateFromCertStore(certificateThumbprintOrSubjectName);
            var handler = new HttpClientHandler();
            handler.ClientCertificateOptions = ClientCertificateOption.Manual;
            handler.SslProtocols = SslProtocols.Tls12;
            handler.ServerCertificateCustomValidationCallback = (_, _, _, _) => true;
            handler.AutomaticDecompression = System.Net.DecompressionMethods.GZip;
            if (certificate != null)
            {
                handler.ClientCertificates.Add(certificate);
            }
            else
            {
                Log.Warning(
                    "Certificate could not be found in the Windows certificate store. Certificate Identifier: {CertificateIdentifier}",
                    certificateThumbprintOrSubjectName);
            }
            return handler;
        }
        catch (Exception ex)
        {
            throw new Exception(ex);
        }
    }


    private static X509Certificate2 GetCertificateFromCertStore(string certificateThumbprintOrSubjectName)
    {
        var searchValue = certificateThumbprintOrSubjectName;

        if (string.IsNullOrWhiteSpace(searchValue))
            return null;

        using var certStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
        certStore.Open(OpenFlags.ReadOnly);

        return certStore.FindCertificate(X509FindType.FindByThumbprint, searchValue) ??
               certStore.FindCertificate(X509FindType.FindBySubjectName, searchValue);
    }

    private static X509Certificate2 FindCertificate(this X509Store certStore, X509FindType findType, string searchValue)
    {
        var certificate = certStore.Certificates
            .Find(findType, searchValue, true)
            .FirstOrDefault(c => c.HasPrivateKey);

        if (certificate != null)
        {
            Log.Information(
                "Certificate loaded by using windows certificate store. Certificate Identifier: {CertificateIdentifier}",
                searchValue);
        }

        return certificate;
    }
}

Conclusion

By leveraging HttpClientFactory and custom configurations, .NET Core developers can build resilient and efficient HTTP clients. This approach simplifies client management and enhances the flexibility of handling various scenarios. As you integrate these practices into your projects, keep in mind the importance of fine-tuning configurations to match your application's unique requirements.

Http Client
Httpclientfactory
Net Core
C Sharp Programming
Http Client Handler
Recommended from ReadMedium
avatarJiyan Epözdemir
C# 11 Features

What is new in C# 11?

9 min read