When working in applications in ASP.NET Core you might often need to invoke the Web API action methods using HttpClient to check if the endpoints are working fine. To achieve this, you would typically instantiate HttpClient and use the instance to invoke your action methods. However, there are certain downsides to using HttpClient directly, mainly having to do with managing the lifetimes of the instances manually.

You can avoid these downsides by using IHttpClientFactory to create your HttpClient instances. Introduced in .NET Core 2.1, IHttpClientFactory provides a central place to name, configure, and create HttpClient instances and manages the pooling and lifetimes of the instances automatically.

I’ve discussed HttpClient and HttpClientFactory in an earlier article here. This article further discusses HttpClient and IHttpClientFactory with code examples to illustrate the concepts covered. To work with the code examples provided, you should have Visual Studio 2019 installed in your system. If you don’t already have a copy, you can download Visual Studio 2019 here .

  • Launch the Visual Studio IDE.
  • Click on “Create new project.”
  • In the “Create new project” window, select “ASP.NET Core Web Application” from the list of templates displayed.
  • Click Next.
  • In the “Configure your new project” window, specify the name and location for the new project.
  • Optionally check the “Place solution and project in the same directory” check box, depending on your preferences.
  • Click Create.
  • In the “Create a New ASP.NET Core Web Application” window shown next, select .NET Core as the runtime and ASP.NET Core 3.1 (or later) from the drop-down list at the top.
  • Select “Web Application (Model-View-Controller)” as the project template to create a new ASP.NET Core MVC application.
  • Ensure that the check boxes “Enable Docker Support” and “Configure for HTTPS” are unchecked as we won’t be using those features here.
  • Ensure that Authentication is set to “No Authentication” as we won’t be using authentication either.
  • Click Create.
  • Following these steps should create a new ASP.NET Core MVC project in Visual Studio 2019. In the new project, create a new API controller and save it using the default name, i.e., ValuesController. We’ll use this project in the sections that follow.

    HttpClient challenges

    Although the HttpClient class doesn’t implement the IDisposable interface directly, it extends the System.Net.Http.HttpMessageInvoker class, which does implement IDisposable. Nevertheless, when working with HttpClient instances, you shouldn’t be disposing of them. Although you can call the Dispose method on an HttpClient instance, it is not a recommended practice.

    What should you do instead? One option is to make the HttpClient instance static or wrap a non-static instance of the HttpClient inside a custom class and make it a singleton class. But a better alternative is to use IHttpClientFactory to retrieve an instance of HttpClient and then use the instance for calling action methods.

    IHttpClientFactory and HttpClientFactory

    IHttpClientFactory is an interface that is implemented by the DefaultHttpClientFactory class, which is an opinionated factory. The DefaultHttpClientFactory implements the IHttpClientFactory and IHttpMessageHandlerFactory interfaces. IHttpClientFactory was introduced to provide ASP.NET Core with excellent built-in support for creating, caching, and disposing of HttpClient instances.

    Note that HttpClientFactory (discussed in my earlier article ) is just a helper to create HttpClient instances configured with the handlers provided. This class has the following methods:

    Create(DelegatingHandler[]) Create(HttpMessageHandler, DelegatingHandler[]) CreatePipeline(HttpMessageHandler, IEnumerable )

    The overloaded Create methods of the HttpClientFactory class look like this:

    public static HttpClient Create(params DelegatingHandler[] handlers)
    return Create(new HttpClientHandler(), handlers);
    

    Source: https://github.com/aspnet/HttpClientFactory/blob/master/src/Microsoft.Extensions.Http/IHttpClientFactory.cs

    public static HttpClient Create(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers)
    HttpMessageHandler pipeline = CreatePipeline(innerHandler, handlers);
    return new HttpClient(pipeline);
    

    Source: https://github.com/aspnet/HttpClientFactory/blob/master/src/Microsoft.Extensions.Http/IHttpClientFactory.cs

    Both HttpClientFactory and IHttpClientFactory were introduced to better manage the lifetime of HttpMessageHandler instances.

    Why use IHttpClientFactory?

    When you dispose of a HttpClient instance, the connection remains open for up to four minutes. Further, the number of sockets that you can open at any point in time has a limit — you can’t have too many sockets open at once. So when you use too many HttpClient instances, you might end up exhausting your supply of sockets.

    Here’s where IHttpClientFactory comes to the rescue. You can take advantage of IHttpClientFactory to create HttpClient instances for invoking HTTP API methods by adhering to the best practices to avoid issues faced with HttpClient. The primary goal of IHttpClientFactory in ASP.NET Core is to ensure that HttpClient instances are created using the factory while at the same time eliminating socket exhaustion.

    Register an IHttpClientFactory instance in ASP.NET Core

    You can register an instance of type IHttpClientFactory in the ConfigureServices method of the Startup class by calling the AddHttpClient extension method on the IServiceCollection instance as shown in the code snippet given below.

    public void ConfigureServices(IServiceCollection services)
       services.AddControllersWithViews();
       services.AddHttpClient();
    

    Inject an IHttpClientFactory instance to your controllers in ASP.NET Core

    You can then inject an IHttpClientFactory instance to your controllers as shown in the code snippet given below.

    private IHttpClientFactory _httpClientFactory;       private readonly ILogger<HomeController> _logger;       public HomeController(ILogger<HomeController> logger,       IHttpClientFactory httpClientFactory)             _logger = logger;             _httpClientFactory = httpClientFactory;    //Your action methods go here

    Call your action methods using HttpClient in ASP.NET Core

    To create an HttpClient using IHttpClientFactory, you should call the CreateClient method. Once the HttpClient instance is available, you can use the following code in the Index action method of the HomeController class to invoke the Get method of the ValuesController class.

    public async Task<IActionResult> Index()
       HttpClient httpClient = _httpClientFactory.CreateClient();
       httpClient.BaseAddress = new Uri("http://localhost:1810/");
       var response = await httpClient.GetAsync("/api/values");
       string str = await response.Content.ReadAsStringAsync();
       List<string> data = JsonSerializer.Deserialize<List<string>>(str);
       return View(data);
    

    Use IHttpClientFactory to create and manage HttpClient instances in ASP.NET Core

    There are several ways you can use IHttpClientFactory in your application. These include using IHttpClientFactory directly, using named clients, and using typed clients. 

    The basic or general usage pattern—i.e., using IHttpClientFactory directly—has already been discussed in the preceding sections. Refer to the section “Register an IHttpClientFactory instance” that discusses how you can register an HttpClient instance.

    Using named clients

    If you would like to use HttpClient instances with different configurations, named clients is a good choice. The following code snippet illustrates how you can create a named client.

    services.AddHttpClient("github", c =>
        c.BaseAddress = new Uri("https://api.github.com/");
        c.DefaultRequestHeaders.Add("Accept",
        "application/vnd.github.v3+json");
        c.DefaultRequestHeaders.Add("User-Agent", "This is a test user agent");
    

    Using typed clients

    A typed client is defined using a custom class that wraps an HttpClient instance, encapsulating the logic for calls to all of the endpoints over the HTTP protocol. The following code snippet illustrates how a custom HttpClient class can be defined.

    public class ProductService : IProductService
        private IHttpClientFactory _httpClientFactory;
        private readonly HttpClient _httpClient;
        private readonly string _baseUrl = "http://localhost:1810/";
        public ProductService(HttpClient httpClient)
            _httpClient = httpClient;
        public async Task<Catalog> GetAllProducts()
            _httpClient = _httpClientFactory.CreateClient();
            _httpClient.BaseAddress = new Uri(_baseUrl);
            var uri = "/api/products";
            var result = await _httpClient.GetStringAsync(uri);
            return JsonConvert.DeserializeObject<Product>(result);
    

    The following code snippet shows how you can register your custom typed HttpClient.

    services.AddHttpClient<IProductService, ProductService>();

    Add MessageHandlers to the pipeline in ASP.NET Core

    A Message handler is a class that extends the HttpMessageHandler class, accepts an HTTP request, and returns an HTTP response. If you would like to build your own message handler, you should create a class that extends the DelegatingHandler class.

    You can add HttpMessageHandlers to the request processing pipeline. If you’re using a named client, you can use the following code in the ConfigureServices method of the Startup class to add message handlers to the pipeline.

    public void ConfigureServices(IServiceCollection services)
        services.AddHttpClient("github", c =>
            c.BaseAddress = new Uri("https://api.github.com/");
        .AddHttpMessageHandler<DemoHandler>();
        services.AddTransient<DemoHandler>();
    

    IHttpClientFactory is an opinionated factory that has been available since .NET Core 2.1. If you use IHttpClientFactory to create your HttpClient instances, then the pooling and lifetime of the underlying HttpClientMessagehandler instances are managed for you automatically. IHttpClientFactory also takes care of common concerns such as logging.

  • How to use the ProblemDetails middleware in ASP.NET Core
  • How to create route constraints in ASP.NET Core
  • How to manage user secrets in ASP.NET Core
  • How to build gRPC applications in ASP.NET Core
  • How to redirect a request in ASP.NET Core
  • How to use attribute routing in ASP.NET Core
  • How to pass parameters to action methods in ASP.NET Core MVC
  • How to use API Analyzers in ASP.NET Core
  • How to use route data tokens in ASP.NET Core
  • How to use API versioning in ASP.NET Core
  • How to use Data Transfer Objects in ASP.NET Core 3.1
  • How to handle 404 errors in ASP.NET Core MVC
  • How to use dependency injection in action filters in ASP.NET Core 3.1
  • How to use the options pattern in ASP.NET Core
  • How to use endpoint routing in ASP.NET Core 3.0 MVC
  • How to export data to Excel in ASP.NET Core 3.0
  • How to use LoggerMessage in ASP.NET Core 3.0
  • How to send emails in ASP.NET Core
  • How to log data to SQL Server in ASP.NET Core
  • How to schedule jobs using Quartz.NET in ASP.NET Core
  • How to return data from ASP.NET Core Web API
  • How to format response data in ASP.NET Core
  • How to consume an ASP.NET Core Web API using RestSharp
  • How to perform async operations using Dapper
  • How to use feature flags in ASP.NET Core
  • How to use the FromServices attribute in ASP.NET Core
  • How to work with cookies in ASP.NET Core
  • How to work with static files in ASP.NET Core
  • How to use URL Rewriting Middleware in ASP.NET Core
  • How to implement rate limiting in ASP.NET Core
  • How to use Azure Application Insights in ASP.NET Core
  • Using advanced NLog features in ASP.NET Core
  • How to handle errors in ASP.NET Web API
  • How to implement global exception handling in ASP.NET Core MVC
  • How to handle null values in ASP.NET Core MVC
  • Advanced versioning in ASP.NET Core Web API
  • How to work with worker services in ASP.NET Core
  • How to use the Data Protection API in ASP.NET Core
  • How to use conditional middleware in ASP.NET Core
  • How to work with session state in ASP.NET Core
  • How to write efficient controllers in ASP.NET Core
  • Angular 19 to make standalone the default for components

    The standalone feature lets developers build apps that do not depend on NgModule and is now the recommended way to write Angular code.
    By Paul Krill Sep 04, 2024 2 mins Web Development Angular Development Libraries and Frameworks

    What is HTTP/3? The next-generation web protocol

    HTTP/3 breaks from HTTP/2 by adopting the QUIC protocol over TCP. Here's a first look at the new standard and what it means for web developers.
    By Matthew Tyson Sep 04, 2024 8 mins Web Development Software Development

    Ruby on Rails gets better production defaults

    Version 7.2 of the longstanding web framework arrives with improved production defaults and a new dev container config.
    By Paul Krill Aug 14, 2024 2 mins Web Development Programming Languages

    Google unveils Flutter GPU API, Dart updates

    Flutter GPU, available in an early preview, is a low-level graphics API for building rendering packages from scratch using Dart and GLSL.
    By Paul Krill Aug 07, 2024 3 mins Mobile Development Web Development Development Tools

    Joydip Kanjilal is a Microsoft Most Valuable Professional (MVP) in ASP.NET, as well as a speaker and the author of several books and articles. He received the prestigious MVP award for 2007, 2008, 2009, 2010, 2011, and 2012.

    He has more than 20 years of experience in IT, with more than 16 years in Microsoft .Net and related technologies. He has been selected as MSDN Featured Developer of the Fortnight (MSDN) and as Community Credit Winner several times.

    He is the author of eight books and more than 500 articles. Many of his articles have been featured at Microsoft’s Official Site on ASP.Net .

    He was a speaker at the Spark IT 2010 event and at the Dr. Dobb’s Conference 2014 in Bangalore. He has also worked as a judge for the Jolt Awards at Dr. Dobb's Journal. He is a regular speaker at the SSWUG Virtual Conference , which is held twice each year.

    More from this author

    analysis

    Using the Pinecone vector database in .NET

    By Simon Bisson
    Sep 12, 2024 7 mins
    Microsoft .NET Generative AI Development Tools
    how-to

    Using PostgreSQL as a vector database in RAG

    By Nitin Borwankar
    Sep 12, 2024 15 mins
    PostgreSQL Generative AI Artificial Intelligence
    feature

    Oracle CloudWorld 2024: Latest news and insights

    By Anirban Ghoshal
    Sep 12, 2024 7 mins
    Cloud Computing
    video

    How to implement "modes" in software, with a game as an example

    Sep 12, 2024 4 mins
    Python