How to send synchronous requests with HttpClient in C#

By FoxLearn 3/6/2025 2:38:45 AM   4
In .NET 5 and above, the HttpClient Sync API methods Send() and ReadAsStream() provide a way to send HTTP requests synchronously, allowing you to avoid the complexities of async code (like sync-over-async)

HttpClient was primarily designed for asynchronous communication, and its convenience methods (such as GetAsync() and ReadAsStringAsync()) are all async. Currently, no sync versions of these convenience methods exist. The Sync API in HttpClient provides the minimum necessary methods for synchronous use.

How to send synchronous GET and POST requests with HttpClient

1. Synchronous GET Request

For example, How to send a synchronous GET request and deserialize the JSON response using System.Text.Json:

using System.Net.Http;
using System.Text.Json;

// Reuse these instances as needed
var httpClient = new HttpClient();
var jsonOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);

// Make the sync GET request
using (var request = new HttpRequestMessage(HttpMethod.Get, "https://api.example.com/user"))
{
    var response = httpClient.Send(request);

    response.EnsureSuccessStatusCode();

    using var stream = response.Content.ReadAsStream();
    var user = JsonSerializer.Deserialize<User>(stream, jsonOptions);

    Console.WriteLine($"User {user.Name} is {user.Age} years old.");
}

In this example, we send a GET request to https://api.example.com/user and expect the response to be JSON, then we deserialize the content stream into a User object using System.Text.Json.

Output:

User John Doe is 30 years old.

2. Synchronous POST Request

For example, How to send a synchronous POST request. We will send JSON data and read the response content as a string using StreamReader:

using System.Net.Http;
using System.Text.Json;
using System.IO;

// Reuse these instances as needed
var httpClient = new HttpClient();
var jsonOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);

// Make the sync POST request
using (var request = new HttpRequestMessage(HttpMethod.Post, "https://api.example.com/submit"))
{
    var json = JsonSerializer.Serialize(new Submission() { Title = "New Post", Content = "This is a new post." });
    request.Content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

    var response = httpClient.Send(request);
    response.EnsureSuccessStatusCode();

    using var streamReader = new StreamReader(response.Content.ReadAsStream());
    Console.WriteLine(streamReader.ReadToEnd());

    // Note: StreamReader automatically disposes of the stream
}

In this case, we send a POST request with a JSON body containing a Submission object, then we read and output the response body as a string using StreamReader.

Output:

Submission received: New Post

With .NET 5 and above, sending synchronous HTTP requests using HttpClient is simple, but requires manually handling streams. While HttpClient was designed for async operations, using the synchronous Send() and ReadAsStream() methods allows you to perform blocking requests when necessary.