Ebooks

C# HttpClient tutorial

C# HttpClient tutorial shows how to create HTTP requests with HttpClient in C#. In the examples, we create simple GET and POST requests.

The Hypertext Transfer Protocol (HTTP) is an application protocol for distributed, collaborative, hypermedia information systems. HTTP is the foundation of data communication for the World Wide Web.

HttpClient is a base class for sending HTTP requests and receiving HTTP responses from a resource identified by a URI.

C# HttpClient status code

HTTP response status codes indicate whether a specific HTTP request has been successfully completed. Responses are grouped in five classes:

Program.cs
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace HttpClientStatus
{
    class Program
    {
        static async Task Main(string[] args)
        {
            using var client = new HttpClient();

            var result = await client.GetAsync("http://webcode.me");
            Console.WriteLine(result.StatusCode);
        }
    }
}

The example creates a GET request to a small website. We get the status code of the request.

using var client = new HttpClient();

A new HttpClient is created.

var result = await client.GetAsync("http://webcode.me");

The GetAsync() method sends a GET request to the specified Uri as an asynchronous operation. The await operator suspends the evaluation of the enclosing async method until the asynchronous operation completes. When the asynchronous operation completes, the await operator returns the result of the operation, if any.

$ dotnet run
OK

We get the 200 OK status code; the website is up.

C# HttpClient GET request

The GET method requests a representation of the specified resource.

Program.cs
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace HttpClientEx
{
    class Program
    {
        static async Task Main(string[] args)
        {
            using var client = new HttpClient();
            var content = await client.GetStringAsync("http://webcode.me");

            Console.WriteLine(content);
        }
    }
}

The example issues a GET request to the webcode.me website. It outputs the simple HTML code of the home page.

var content = await client.GetStringAsync("http://webcode.me");

The GetStringAsync() sends a GET request to the specified Uri and returns the response body as a string in an asynchronous operation.

$ dotnet run
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My html page</title>
</head>
<body>

    <p>
        Today is a beautiful day. We go swimming and fishing.
    </p>

    <p>
         Hello there. How are you?
    </p>

</body>
</html>

This is the output.

C# HttpClient HEAD request

The HTTP HEAD method requests the headers that are returned if the specified resource would be requested with an HTTP GET method.

Program.cs
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace HttpClientHead
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var url = "http://webcode.me";
            using var client = new HttpClient();

            var result = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url));

            Console.WriteLine(result);
        }
    }
}

The example issues a HEAD request.

$ dotnet run
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1,
Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
    Server: nginx/1.6.2
    Date: Sat, 12 Oct 2019 19:55:14 GMT
    Connection: keep-alive
    ETag: "5d32ffc5-15c"
    Accept-Ranges: bytes
    Content-Type: text/html
    Content-Length: 348
    Last-Modified: Sat, 20 Jul 2019 11:49:25 GMT
}

This are the header fields of the response.

C# HttpClient POST request

The HTTP POST method sends data to the server. The type of the body of the request is indicated by the Content-Type header.

$ dotnet add package Newtonsoft.Json

We need to add the Newtonsoft.Json package to process JSON data.

Program.cs
using System;
using System.Text;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace HttpClientPost
{
    class Person
    {
        public string Name { get; set; }
        public string Occupation { get; set; }

        public override string ToString()
        {
            return $"{Name}: {Occupation}";
        }
    }

    class Program
    {
        static async Task Main(string[] args)
        {
            var person = new Person();
            person.Name = "John Doe";
            person.Occupation = "gardener";

            var json = JsonConvert.SerializeObject(person);
            var data = new StringContent(json, Encoding.UTF8, "application/json");

            var url = "https://httpbin.org/post";
            using var client = new HttpClient();

            var response = await client.PostAsync(url, data);

            string result = response.Content.ReadAsStringAsync().Result;
            Console.WriteLine(result);
        }
    }
}

In the example, we send a POST request to https://httpbin.org/post website, which is an online testing service for developers.

var person = new Person();
person.Name = "John Doe";
person.Occupation = "gardener";

var json = JsonConvert.SerializeObject(person);
var data = new StringContent(json, Encoding.UTF8, "application/json");

We turn an object into a JSON data with the help of the Newtonsoft.Json package.

var response = await client.PostAsync(url, data);

We send an asynchronous POST request with the PostAsync() method.

string result = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(result);

We read the returned data and print it to the console.

$ dotnet run
{
    "args": {},
    "data": "{\"Name\":\"John Doe\",\"Occupation\":\"gardener\"}",
    "files": {},
    "form": {},
    "headers": {
    "Content-Length": "43",
    "Content-Type": "application/json; charset=utf-8",
    "Host": "httpbin.org"
    },
    "json": {
    "Name": "John Doe",
    "Occupation": "gardener"
    },
    ...
    "url": "https://httpbin.org/post"
}

This is the output.

C# HttpClient JSON request

JSON (JavaScript Object Notation) is a lightweight data-interchange format. This format is easy for humans to read and write and for machines to parse and generate. It is a less verbose and more readable alternative to XML. The official Internet media type for JSON is application/json.

Program.cs
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;

namespace HttpClientJson
{
    class Contributor
    {
        public string Login { get; set; }
        public short Contributions { get; set; }

        public override string ToString()
        {
            return $"{Login,20}: {Contributions} contributions";
        }
    }

    class Program
    {
        private static async Task Main()
        {
            using var client = new HttpClient();

            client.BaseAddress = new Uri("https://api.github.com");
            client.DefaultRequestHeaders.Add("User-Agent", "C# console program");
            client.DefaultRequestHeaders.Accept.Add(
                    new MediaTypeWithQualityHeaderValue("application/json"));

            var url = "repos/symfony/symfony/contributors";
            HttpResponseMessage response = await client.GetAsync(url);
            response.EnsureSuccessStatusCode();
            var resp = await response.Content.ReadAsStringAsync();

            List<Contributor> contributors = JsonConvert.DeserializeObject<List<Contributor>>(resp);
            contributors.ForEach(Console.WriteLine);
        }
    }
}

The example generates a GET request to to Github. It finds out the top contributors of the Symfony framework. It uses the Newtonsoft.Json to work with JSON.

client.DefaultRequestHeaders.Add("User-Agent", "C# console program");

In the request header, we specify the user agent.

client.DefaultRequestHeaders.Accept.Add(
    new MediaTypeWithQualityHeaderValue("application/json"));

In the accept header value, we tell that JSON is an acceptable response type.

var url = "repos/symfony/symfony/contributors";
HttpResponseMessage response = await client.GetAsync(url);
var resp = await response.Content.ReadAsStringAsync();

We generate a request and read the content asynchronously.

List<Contributor> contributors = JsonConvert.DeserializeObject<List<Contributor>>(resp);
contributors.ForEach(Console.WriteLine);

We transform the JSON response into a list of Contributor objects with the JsonConvert.DeserializeObject() method.

C# HttpClient download image

The GetByteArrayAsync() sends a GET request to the specified Uri and returns the response body as a byte array in an asynchronous operation.

Program.cs
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;

namespace HttpClientDownloadImage
{
    class Program
    {
        static async Task Main(string[] args)
        {
            using var httpClient = new HttpClient();
            var url = "http://webcode.me/favicon.ico";
            byte[] imageBytes = await httpClient.GetByteArrayAsync(url);

            string documentsPath = System.Environment.GetFolderPath(
                    System.Environment.SpecialFolder.Personal);

            string localFilename = "favicon.ico";
            string localPath = Path.Combine(documentsPath, localFilename);
            File.WriteAllBytes(localPath, imageBytes);
        }
    }
}

In the example, we download an image from the webcode.me website. The image is written to the user's Documents folder.

byte[] imageBytes = await httpClient.GetByteArrayAsync(url);

The GetByteArrayAsync() returns the image as an array of bytes.

string documentsPath = System.Environment.GetFolderPath(
    System.Environment.SpecialFolder.Personal);

We determine the Documents folder with the GetFolderPath() method.

File.WriteAllBytes(localPath, imageBytes);

The bytes are written to the disk with the File.WriteAllBytes() method.

C# HttpClient Basic authentication

In HTTP protocol, basic access authentication is a method for an HTTP user agent (such as a web browser or a console application) to provide a user name and password when making a request. In basic HTTP authentication, a request contains a header field in the form of Authorization: Basic <credentials>, where credentials is the base64 encoding of id and password joined by a single colon :.

Note: The credentials are not encrypted; therefore, HTTP basic authentication must be used with the HTTPS protocol.

HTTP Basic authentication is the simplest technique for enforcing access controls to web resources. It does not require cookies, session identifiers, or login pages; rather, HTTP Basic authentication uses standard fields in the HTTP header.

Program.cs
using System;
using System.Text;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace HttpClientAuth
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var userName = "user7";
            var passwd = "passwd";
            var url = "https://httpbin.org/basic-auth/user7/passwd";

            using var client = new HttpClient();

            var authToken = Encoding.ASCII.GetBytes($"{userName}:{passwd}");
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
                    Convert.ToBase64String(authToken));

            var result = await client.GetAsync(url);

            var content = await result.Content.ReadAsStringAsync();
            Console.WriteLine(content);
        }
    }
}

The example sends credentials to the httpbin.org website.

var authToken = Encoding.ASCII.GetBytes($"{userName}:{passwd}");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
        Convert.ToBase64String(authToken));

Here we build the authentication header.

var url = "https://httpbin.org/basic-auth/user7/passwd";

The URL contains authentication details because we test it with the httpbin.org website. This way we don't need to set up our own server. Authentication details are never put into the URL, of course.

$ dotnet run
{
    "authenticated": true,
    "user": "user7"
}

This is the output.

In this tutorial, we have used C# HttpClient to create HTTP requests.

You might also be interested in the following related tutorials: C# tutorial, MySQL C# tutorial, Date and time in C#, Reading a web page in C#, or C# Winforms tutorial.