C#
JSON
HTTP POST
API
Web Development

Send JSON via POST in C and Receive the JSON returned?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C#, the standard way to send JSON with an HTTP POST request is to serialize an object, wrap it in StringContent, and send it with HttpClient. The response can then be read as JSON and deserialized back into a typed object or handled as raw text, depending on how strict you want the contract to be.

Define Request and Response Models

Strongly typed request and response classes make the code safer and easier to maintain than string concatenation.

csharp
1public sealed class CreateUserRequest
2{
3    public string Name { get; set; } = "";
4    public string Email { get; set; } = "";
5}
6
7public sealed class CreateUserResponse
8{
9    public int Id { get; set; }
10    public string Status { get; set; } = "";
11}

With these types in place, the API contract becomes obvious in code instead of being hidden inside ad hoc JSON literals.

Send JSON with HttpClient

Use System.Text.Json for serialization and HttpClient for the request itself.

csharp
1using System;
2using System.Net.Http;
3using System.Text;
4using System.Text.Json;
5using System.Threading.Tasks;
6
7public static class ApiClient
8{
9    private static readonly HttpClient Http = new HttpClient();
10
11    public static async Task<CreateUserResponse?> CreateUserAsync()
12    {
13        var payload = new CreateUserRequest
14        {
15            Name = "Ava",
16            Email = "[email protected]"
17        };
18
19        string json = JsonSerializer.Serialize(payload);
20        using var content = new StringContent(json, Encoding.UTF8, "application/json");
21
22        using HttpResponseMessage response =
23            await Http.PostAsync("https://example.com/api/users", content);
24
25        response.EnsureSuccessStatusCode();
26
27        string responseJson = await response.Content.ReadAsStringAsync();
28        return JsonSerializer.Deserialize<CreateUserResponse>(responseJson);
29    }
30}

This is the core pattern: serialize, post, verify status, then deserialize the response body.

Using PostAsJsonAsync

If you want less boilerplate, System.Net.Http.Json provides convenience extensions.

csharp
1using System.Net.Http;
2using System.Net.Http.Json;
3using System.Threading.Tasks;
4
5public static class ApiClient
6{
7    private static readonly HttpClient Http = new HttpClient();
8
9    public static async Task<CreateUserResponse?> CreateUserAsync()
10    {
11        var payload = new CreateUserRequest
12        {
13            Name = "Ava",
14            Email = "[email protected]"
15        };
16
17        using HttpResponseMessage response =
18            await Http.PostAsJsonAsync("https://example.com/api/users", payload);
19
20        response.EnsureSuccessStatusCode();
21        return await response.Content.ReadFromJsonAsync<CreateUserResponse>();
22    }
23}

This is cleaner for ordinary JSON APIs, though the explicit version remains useful when you need custom headers, serializer options, or manual logging of the raw payload.

Handle Errors Deliberately

A successful HTTP POST can still return invalid JSON, and a failed request should not be silently ignored. Good client code distinguishes:

  • transport failures
  • non-success status codes
  • JSON parse failures
csharp
1try
2{
3    CreateUserResponse? result = await ApiClient.CreateUserAsync();
4    Console.WriteLine(result?.Status);
5}
6catch (HttpRequestException ex)
7{
8    Console.WriteLine("HTTP error: " + ex.Message);
9}
10catch (JsonException ex)
11{
12    Console.WriteLine("JSON error: " + ex.Message);
13}

That separation makes production issues easier to diagnose because you can see whether the failure came from the network, the server, or the response format.

Reuse HttpClient

Do not create a new HttpClient for every request unless you have a very specific reason. Reusing it avoids unnecessary socket churn and is the normal pattern in modern .NET code.

If you are in ASP.NET Core, the preferred production approach is usually IHttpClientFactory, but the core POST-plus-JSON flow remains the same.

Common Pitfalls

One common mistake is sending JSON text without the application/json content type. Some servers will reject the request or parse it incorrectly.

Another is building JSON by hand with string concatenation. That is fragile, error-prone, and unnecessary when serializers already exist.

Developers also sometimes ignore non-success status codes and try to deserialize the error body as if it were the normal response schema. Check the status first.

Finally, be careful with HttpClient lifetime. Creating and disposing it for every call can cause avoidable network problems under load.

Summary

  • Use HttpClient and JSON serialization to POST structured payloads in C#.
  • Strongly typed request and response models make the code easier to maintain.
  • 'PostAsJsonAsync is a convenient shortcut for common cases.'
  • Always handle HTTP failures and JSON parsing errors separately.
  • Reuse HttpClient instead of creating one per request.

Course illustration
Course illustration

All Rights Reserved.