HTTP client in C#: making requests correctly from A to Z

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

HTTP client in C#: making requests correctly from A to Z

\n\n

In modern development on the .NET platform, working with HTTP requests is one of the key tasks. Whether it's integration with an external REST API, sending data to a server, or downloading web pages — proper use of HttpClient in C# is critical for application performance and stability. In this article, we will cover all aspects of working with an HTTP client in C#: from basic examples to advanced techniques, error handling, and best practices.

\n\n

1. Basics of working with HttpClient in C#

\n\n

HttpClient is the main class in .NET for sending HTTP requests and receiving responses. It is located in the System.Net.Http namespace and is available starting from .NET Framework 4.5 and all versions of .NET Core/.NET 5+.

\n\n

Important rule: HttpClient is designed for reuse. Creating a new instance for each request is an anti-pattern that can lead to socket exhaustion. Instead, use a single static or singleton instance.

\n\n

Basic example of a GET request:

\n\n
using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nclass Program\n{\n    private static readonly HttpClient client = new HttpClient();\n\n    static async Task Main(string[] args)\n    {\n        try\n        {\n            HttpResponseMessage response = await client.GetAsync("https://api.example.com/data");\n            response.EnsureSuccessStatusCode();\n            string responseBody = await response.Content.ReadAsStringAsync();\n            Console.WriteLine(responseBody);\n        }\n        catch (HttpRequestException e)\n        {\n            Console.WriteLine($"Request error: {e.Message}");\n        }\n    }\n}
\n\n

In this example, we create a static HttpClient, send a GET request, check the success of the response using EnsureSuccessStatusCode(), and read the response body as a string.

\n\n

2. Types of HTTP requests and working with headers

\n\n

In addition to GET, HttpClient supports all major HTTP methods: POST, PUT, DELETE, PATCH, and others. Let's look at sending a POST request with JSON data — this is the most common scenario when working with REST APIs.

\n\n

Example of a POST request with JSON:

\n\n
using System;\nusing System.Net.Http;\nusing System.Text;\nusing System.Text.Json;\nusing System.Threading.Tasks;\n\nclass Program\n{\n    private static readonly HttpClient client = new HttpClient();\n\n    static async Task Main(string[] args)\n    {\n        var data = new { Name = "John", Age = 30 };\n        string json = JsonSerializer.Serialize(data);\n        var content = new StringContent(json, Encoding.UTF8, "application/json");\n\n        try\n        {\n            HttpResponseMessage response = await client.PostAsync("https://api.example.com/users", content);\n            response.EnsureSuccessStatusCode();\n            string result = await response.Content.ReadAsStringAsync();\n            Console.WriteLine($"User created: {result}");\n        }\n        catch (HttpRequestException e)\n        {\n            Console.WriteLine($"Error: {e.Message}");\n        }\n    }\n}
\n\n

Working with headers: APIs often require passing authentication tokens or other headers. They can be added in two ways:

\n\n
    \n
  • Globally — via the DefaultRequestHeaders property (for all client requests).
  • \n
  • Locally — via the Headers collection in the HttpRequestMessage object (for a specific request).
  • \n
\n\n

Example of adding an Authorization header:

\n\n
// Globally\nclient.DefaultRequestHeaders.Authorization = \n    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "your-token");\n\n// Locally\nvar request = new HttpR                

Blogs

Book Recommendations