Review of the HttpClient for C# Developers

Introduction

In more recent years, developers in .NET land—who are aware of its existence—have been making use of the HttpClient class. If you haven’t heard of it, or know of it but never used it, this article will take you through the basics.

You’ll be shown some code, so if you would like to follow along, I’ll be using a .NET 4.6.2 console application. Along with that, I’ll use an ASP.NET Core 1.1 Web application that will service our need for some end points to grab some data from.

Getting Started

To kick things off, I’ve created my project with the two applications previously mentioned. And, this project looks like this…

The project setup
Figure 1: The project setup

The ASP.NET Core project was created using the default webapi template, set with no authentication using MVC. You can confirm if MVC is in use by looking in the startup.cs; in the configure method, you’ll see…

public void Configure(IApplicationBuilder app,
   IHostingEnvironment env, ILoggerFactory
   loggerFactory)
{
   loggerFactory.AddConsole(Configuration
      .GetSection("Logging"));
   loggerFactory.AddDebug();

   app.UseMvc();
}

On creation of the project, you should also find a ValuesController, already created for you. I’ve edited mine to look something like this…

[Route("api/[controller]")]
public class ValuesController : Controller
{
   // GET api/values
   [HttpGet]
   public IEnumerable<string> Get()
   {
      return new string[] { "Hello",
         "from Code Guru" };
   }
}

So now, we have a basic Web API from which we can grab a little data from our console application. If you want to run this, just to make sure it’s working, I recommend opening a command project at the location of the project, and type:

dotnet run

If everything is good, you’ll be presented with what you see in Figure 2.

The ASP.NET Core application running
Figure 2: The ASP.NET Core application running

If you navigate to the following URL via your browser, http://localhost:5000/api/values, you’ll see the response as we defined in your controller.

If you’re all good to go, let’s move on to the console application and see the HttpClient in action.

The HttpClient

To start with, let’s do a simple get on the endpoint we created, and observe the results from our console application. My Main method looks something like this…

static void Main(string[] args)
{
   GetAsync().Wait();
}

static async Task GetAsync()
{
   using (var httpClient = new HttpClient())
   {
      httpClient.BaseAddress = new
         Uri("http://localhost:5000");

      var results = await
         httpClient.GetStringAsync("api/values");

      Console.WriteLine(results);
   }
}

Note here that the HttpClient implements IDisposable, and therefore a using statement can be taken advantage of here to clean up the resources for us implicitly. And, if we run this console application, while running the ASP.NET Core application, we can observe behaviour such as show in Figure 3.

The console application running in tandem with the Web API
Figure 3: The console application running in tandem with the Web API

Let’s go ahead now and return something that we are not expecting. This could be a response given when a resource is not found.

I’ve altered the code to look like this…

[HttpGet]
public IEnumerable<string> Get()
{
   //return new string[] { "Hello",
      "from Code Guru" };
   Response.StatusCode = 404;
   return null;
}

We have nothing to return because the resource was not found. But, how does the HttpClient.GetStringAsync() method deal with this? Well, it throws an exception, which we need to deal with. If we were being heavy handed, we could catch all exceptions in a try/catch loop; but this is messy and an anti-pattern. So, is there a better way to deal with this?

The answer is yes! Let’s look at a way to call our endpoint, one thatich allows us to manage the response in a much more ordered fashion. Consider the following code…

static async Task GetAsync()
{
   using (var httpClient = new HttpClient())
   {
      httpClient.BaseAddress = new
         Uri("http://localhost:5000");

      HttpResponseMessage response = await
         httpClient.GetAsync("api/values");

      if (!response.IsSuccessStatusCode)
      {
         Console.WriteLine(response.StatusCode);
      }
      else
      {
         Console.WriteLine(await
            response.Content.ReadAsStringAsync());
      }
   }
}

By making use of the GetAsync method rather than the GetStringAsync, our client will give us an object that we can check for success, and grab a few other bits of data, too. This is my preferred way to use HttpClient and is good for many situations when the response is not quite what we expect. Running the previous code, with the changes made to the API earlier, I can see the following output in my console window…

Our 'Not Found' response
Figure 4: Our ‘Not Found’ response

More Verbs

Moving on from what we’ve seen so far, let’s now look at another HTTP verb, Post. The HttpClient class supports this verb, as well as put and delete. Creating a post is very simple; take a look at the following code…

using(var stringContent = new StringContent
  ("The content of my post", Encoding.UTF8))
{
   HttpResponseMessage response = await
      httpClient.PostAsync("api/values",
      stringContent);
}

The post method expects HttpContent passed through its second parameter; for this example, I’m going with StringContent, which is derived from HttpContent, where I’ve passed a simple string through its constructor.

All that remains is to set up an endpoint to receive this post in your Web API. I’ll leave this task to your good self to complete when time is convenient for you.

At this point, I’m going to conclude this article, which I hope has been useful to you. Speaking for myself, the .NET HttpClient class is a bit of a workhorse in many of my projects. It’s simple and easy to implement, and covers many scenarios out of the box.

If you have any questions about this article, you can always find me on Twitter @GLanata.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read