Learn ASP.NET Core 3.0 : MVC, Razor Pages, Web API, Entity Framework Core, and Blazor.
Microsoft's official documentation can be found here. Looking for professional online training courses? Next weekend batches are starting in November 2019. More details here.

Use IHttpClientFactory to invoke Web API in ASP.NET Core

If you have worked with ASP.NET Core Web APIs before, chances are you used HttpClient to invoke them. Although instantiating HttpClient directly is a common way of using it, there is a better alternative. Rather than instanting HttpClient yourself you can use IHttpClientFactory to obtain an instance of HttpClient. The HttpClient object thus obtained can be used to invoke the Web API. In this article I discuss three ways to obtain an HttpClient instance using IHttpClientFactory.

The examples discussed in this article assume that you have a Web API as shown below:

[Route("api/[controller]")]
public class ValuesController : Controller
{
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "Hello World!", 
                              "Hello Galaxy!", 
                              "Hello Universe!" };
    }
}

The Values Web API controller contains Get() action that returns an array of strings - Hello World!, Hello Galazy!, and Hello Universe!

This Web API is to be invoked from HomeController. So, you are going to need HttpClient object to accomplish your task.

Let's see various ways to obtain an instance of HttpClient using IHttpClientFactory.

Basic technique to obtain HttpClient

In this technique you use AddHttpClient() on IServiceCollection inside the ConfigureServices() method as shown below:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddControllersWithViews();
    services.AddHttpClient();
}

You can then inject IHttpClientFactory into the HomeController as follows:

 private IHttpClientFactory factory;

public HomeController(IHttpClientFactory client)
{
  this.client = client;
}

Next, you can obtain an instance of HttpClient like this:

public IActionResult Index()
{
  HttpClient client = factory.CreateClient();
  client.BaseAddress = new Uri("https://localhost:44393");
  var response = client.GetAsync("/api/values").Result;
  string jsonData = response.Content.ReadAsStringAsync()
                    .Result;
  List<string> data = JsonSerializer.Deserialize
                      <List<string>>(jsonData);
  return View(data);
}

Notice how the CreateClient() method of IHttpClientFactory is used to obtain an instance of HttpClient. How to create that instance is the job of CreateClient(). Once obtained, you can configure it as per your requirement. For example, here you set the BaseAddress property to the Web API's base address. You then proceed to call GetAsync() to invoke the Get() action of the Web API.

The JSON returned from Get() is deserialized using JsonSerializer class from System.Text.Json namespace. The data is then sent to the Index view to output on the page.

Obtain pre-configured and named client

At times you need HttpClient instances each having a particular configuration. While calling AddHttpClient() method you can also specify the configuration information and name as shown below:

services.AddHttpClient("myclient", o =>
{
    o.BaseAddress = new Uri
("https://localhost:44393");
});

Here, you created a named client called myclient that has certain configuration (BaseAddress in this case). Whenever you need this named instance you can get it like this:

public IActionResult Index()
{
  HttpClient client = factory.CreateClient("myclient");
  var response = client.GetAsync("/api/values").Result;
  string jsonData = response.Content.ReadAsStringAsync()
.Result;
  List<string> data = JsonSerializer.Deserialize
<List<string>>(jsonData);
  return View(client.GetData());
}

Notice that CreateClient() method now specifies the name of the client. Since myclient already has BaseAddress configured in the startup, the code doesn't set the BaseAddress property and proceeds to calling GetAsync() method.

Obtain a typed client

A typed client is the one that encapsulates the required configuration and exposes Web API calls through a set of methods. The following class represents such a typed client:

public class MyTypedClient
{
    public HttpClient Client { get; set; }

    public MyTypedClient(HttpClient client)
    {
        client.BaseAddress = new Uri
("https://localhost:44393");
        this.Client = client;
    }


    public List<string> GetData()
    {
        var response = this.Client.GetAsync
("/api/values").Result;
        string jsonData = response.Content.
ReadAsStringAsync().Result;
        List<string> data = JsonSerializer.
Deserialize<List<string>>(jsonData);
        return data;
    }
}

As you can see, MyTypedClass class has a public property named Client that is of type HttpClient. This property is assigned a value in the constructor through dependency injection. The GetData() method does all the configuration and We API call and returns the required data to the client.

Thus the other parts of the application need not know how an API is being called or what configuration is necessary. Other parts of the system can simply use MyTypedClient object to get the job done.

Once MyTypedClient is ready register it in the ConfigureServices() as shown below:

public void ConfigureServices
(IServiceCollection services)
{
    services.AddControllers();
    services.AddControllersWithViews();
    services.AddHttpClient<MyTypedClient>();
}

To inject an object of MyTypedClient in the HomeController you will write this:

private MyTypedClient client;

public HomeController(MyTypedClient client)
{
    this.client = client;
}

You can then use client typed client object in Index() action as shown below:

public IActionResult Index()
{
  return View(client.GetData());
}

I hope you must have got some idea about the IHttpClientFactory and its utility. You can read more about IHttpClietFactory here.

That's it for now! Keep coding!!


Bipin Joshi is an independent software consultant, trainer, author, yoga mentor, and meditation teacher. He has been programming, meditating, and teaching for 24+ years. He conducts instructor-led online training courses in ASP.NET family of technologies for individuals and small groups. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Ajapa Yoga to interested individuals. To know more about him click here.

Get article updates : Facebook  Twitter  LinkedIn

Posted On : 02 December 2019


Tags : ASP.NET ASP.NET Core MVC .NET Framework C# Visual Studio


Subscribe to our newsletter

Get monthly email updates about new articles, tutorials, code samples, and how-tos getting added to our knowledge base.

  

Receive Weekly Updates