Sending HTTP POST in .NET: From Beginner to Pro in C#

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

How to Send an HTTP POST Request in .NET in C#: From Simple to Complex

\n\n

Imagine your C# application is a courier that needs to deliver a package (data) to a specific address (URL) and receive confirmation (response). This is exactly the task that an HTTP POST request solves. On Stack Overflow, this question gathers thousands of views, and for good reason: working with external APIs, sending forms, uploading data to a server — this is the daily routine of any .NET developer.

\n\n

In this article, we will cover three main ways to send a POST request in .NET (C#), starting with the modern HttpClient and ending with the "legacy" WebRequest. You will learn how to transmit JSON, URL-encoded data, handle errors, and avoid pitfalls that await beginners. Let's go!

\n\n

1. Modern Approach: HttpClient (Recommended)

\n\n

Starting with .NET Framework 4.5 and in all versions of .NET Core / .NET 5+, the HttpClient class is the de facto standard. It is designed for asynchronous work, supports connection reuse, and is easily configurable.

\n\n

1.1. Simple POST with JSON (Most Common Scenario)

\n\n

Let's say we need to send user data to the server in JSON format. Here's what it looks like in real code:

\n\n
using System;\nusing System.Net.Http;\nusing System.Text;\nusing System.Text.Json;\nusing System.Threading.Tasks;\n\npublic class UserService\n{\n    private readonly HttpClient _httpClient;\n\n    public UserService(HttpClient httpClient)\n    {\n        _httpClient = httpClient;\n    }\n\n    public async Task<UserResponse> CreateUserAsync(UserDto newUser)\n    {\n        // 1. Serialize the object to JSON\n        var json = JsonSerializer.Serialize(newUser);\n        var content = new StringContent(json, Encoding.UTF8, "application/json");\n\n        // 2. Send POST\n        HttpResponseMessage response = await _httpClient.PostAsync("https://api.example.com/users", content);\n\n        // 3. Read the response\n        response.EnsureSuccessStatusCode(); // Will throw an exception if status is not 2xx\n\n        var responseBody = await response.Content.ReadAsStringAsync();\n        return JsonSerializer.Deserialize<UserResponse>(responseBody);\n    }\n}\n\n// Usage example\npublic class Program\n{\n    public static async Task Main()\n    {\n        var client = new HttpClient();\n        var service = new UserService(client);\n        \n        var user = new UserDto { Name = "Ivan", Email = "ivan@example.com" };\n        var result = await service.CreateUserAsync(user);\n        Console.WriteLine($"Created user ID: {result.Id}");\n    }\n}\n\npublic class UserDto\n{\n    public string Name { get; set; }\n    public string Email { get; set; }\n}\n\npublic class UserResponse\n{\n    public int Id { get; set; }\n}
\n\n

Important points:

\n
    \n
  • Always use async/await — this prevents the thread from blocking.
  • \n
  • EnsureSuccessStatusCode() — your best friend for quick error checking.
  • \n
  • Do not create a new HttpClient for each request — this leads to socket exhaustion. Use IHttpClientFactory in ASP.NET Core or a single static instance.
  • \n
\n\n

1.2. POST with Form Data (application/x-www-form-urlencoded)

\n\n

Sometimes the API requires data in the format of a regular HTML form. For this, we use FormUrlEncodedContent:

\n\n
public async Task<string> PostFormDataAsync(string username, string password)\n{\n    var formData = new Dictionary<string, string>\n    {\n        { "grant_type", "password" },\n        { "username", username },\n        { "password", password }\n    };\n\n    var content = new FormUrlEncodedContent(formData);\n\n    using var client = new HttpClient();\n    var response = awa                

Blogs

Book Recommendations