C# – How to send synchronous requests with HttpClient

In .NET 5 and above, you can use the HttpClient Sync API methods – Send() and ReadAsStream() – to send HTTP requests synchronously (as opposed to resorting to sync-over-async). Here’s the steps for doing this:

  • Create an instance of HttpRequestMessage.
  • Use the synchronous HttpClient.Send() to send the message.
  • Use the synchronous HttpContent.ReadAsStream() to get the response content.

HttpClient was originally designed for async requests and has many async convenience methods (like GetAsync() and ReadAsStringAsync()). There aren’t sync versions of any of these convenience methods (at least not yet). The Sync API basically has the bare minimum methods needed for using HttpClient without async.

I’ll show examples of sending synchronous GET and POST requests with HttpClient.

Synchronous GET request

Here’s an example of sending a synchronous GET request and deserializing the response content stream with System.Text.Json:

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

//note: save these instances for reuse
var httpClient = new HttpClient();
var jsonOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);

//make the sync GET request
using (var request = new HttpRequestMessage(HttpMethod.Get, "https://localhost:12345/Coder"))
{
	var response = httpClient.Send(request);

	response.EnsureSuccessStatusCode();

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

	Console.WriteLine($"Got {coder.Language} coder named {coder.Name}");
}
Code language: C# (cs)

Notice that you have to deal with the response content as a stream (from HttpContent.ReadAsStream()). If the response content is JSON, you can use System.Text.Json since it can handle deserializing JSON from a stream.

This outputs the following:

Got C# coder named BobCode language: plaintext (plaintext)

Synchronous POST request

Here’s an example of sending a synchronous POST request and reading the response content stream as a string with StreamReader:

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

//note: save these instances for reuse
var httpClient = new HttpClient();
var jsonOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);

//make the sync POST request
using (var request = new HttpRequestMessage(HttpMethod.Post, "https://localhost:12345/Coder"))
{
	var json = JsonSerializer.Serialize(new Coder() { Name = "Bob", Language = "C#" });
	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 disposes the stream for you
}
Code language: C# (cs)

HttpContent.ReadAsStream() returns the content as a MemoryStream. When you want the content as a string, use StreamReader.ReadToEnd() as shown above.

This sends the request and gets back the following response body (read from the content stream):

Posted coder BobCode language: plaintext (plaintext)

Comments are closed.