Implementing a Synchronous HTTP Client in C#.NET
You may be thinking that in 2019 this title is non-sense, and I’d be tempted to agree with you.
Not even I thought that in 2019 I would have found myself needing a synchronous http client implementation.
We have the HttpClient
, right?
Unfortunately, not exactly.
What if you are in a context where you cannot use the asynchronous HttpClient?
Intro — A Unity 3D Story
Quick example: a few days ago I (re)started to use Unity 3D, because I had a nice idea for a simple 3D game and I wanted to implement it.
The architecture of the game is made of two parts:
- The server-side application, developed in ASP.NET Core 2.2, that exposes APIs used by the game
- The client application, that’s the Unity game
Once implemented the server-side APIs, I needed to call them from Unity scripts and I started writing asynchronous code as I do every time I use the HttpClient (GetAsync()
, PostAsync()
, etc.).
And while Visual Studio let me write async/await functions inside my code, Unity itself wasn’t working at all — the fun part is that Unity wasn’t even showing any error… it just didn’t do anything when I executed my scripts.
This made me discover that Unity does not support async/await: I also tried using the Async Await Support package from the Unity Asset Store, but it didn’t work properly and I eventually decided to give up on the async aspect in Unity.
My Decision — The SyncHttpClient
Once I knew that async
/await
isn’t supported by Unity, the only thing left to do was writing synchronous HTTP requests the old way.
How?
Simple. Using the HttpWebRequest
class.
For those of you who don’t know this class, well… it’s been around for a lot of years in .NET, already before the advent of the HttpClient.
This class let’s you create synchronous HTTP requests, that’s all I needed in this case.
The only downside is that you need to write more code to achieve what you need and the code you end up with is more cumbersome than the code you’d write using the HttpClient.
Oh well… patience.
Repository & NuGet Package
If you just want the code you can head directly to the GitHub repository where I published the library or you can even download and use the NuGet Package I published.
Either ways you’re covered — your choice.
Some explanations
The idea behind the HttpWebRequest
is that you actually create the request object and then execute it.
This is how you create an HTTP request object:
var url = "https://yourdomain.com/api/sample";
var request = WebRequest.CreateHttp(url);
request.Method = "GET"; // or "POST", "PUT", "PATCH", "DELETE", etc.
Let’s assume we’re creating a GET
request to a resource.
Once created the request, we have to execute it, in order to obtain the response:
using (var response = (HttpWebResponse)request.GetResponse())
{
// Do something with the response
}
Note that since the HttpWebResponse is IDisposable we wrap its usage in a using
block.
Now we have the response, but we need to actually read it to get its content:
// Get the stream associated with the response
using (var responseStream = response.GetResponseStream())
{
// Get a reader capable of reading the response stream
using (var myStreamReader = new StreamReader(responseStream, Encoding.UTF8))
{
// Read stream content as string
var responseJSON = myStreamReader.ReadToEnd();
// Assuming the response is in JSON format, deserialize it
// creating an instance of TData type (generic type declared before).
data = JsonConvert.DeserializeObject<TData>(responseJSON);
}
}
I placed a comment on every line in the code above, it should be easy to understand.
The thing I’d like to underline is that I used the Newtonsoft.Json NuGet Package to easily hande JSON serialization/deserialization.
Wrap up
The above code is only a sample usage of the HttpWebRequest class: you can find the complete SyncHttpClient
implementation at my GitHub repository — the class exposes generic methods and hides the usage of the HttpWebRequest
class internally, making it very easy to send HTTP requests like we usually do with the HttpClient
class.