HTTP Requests

Making HTTP requests is a common and essential part of working with modern applications. In .NET, the HttpClient class is used to send HTTP requests and receive HTTP responses.

HttpClient basics

The HttpClient class is a high-level abstraction for making HTTP requests and receiving/processing HTTP responses.

HttpRequestMessage

Represents a request message to be sent to an HTTP server. You can configure the request's method, headers, and content.

var request = new HttpRequestMessage(HttpMethod.Get, "https://microsoft.com");
var httpClient = new HttpClient();

var response = await httpClient.SendAsync(request);

Default Headers

HttpClient includes a set of default headers for every request, which can be overridden or added to as needed.

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("X-Secret-Header", "some_secret_value");

var request = new HttpRequestMessage(HttpMethod.Get, "https://yourfavoriteservice.com/some_secret_api");

Authorization

You can set the authorization header to include tokens or credentials for secured endpoints.

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "your_token_here");

var request = new HttpRequestMessage(HttpMethod.Get, "https://yourfavoriteservice.com/some_secret_api");

GET Requests

Use HttpClient to send GET requests to retrieve data from a server.

var httpClient = new HttpClient();
var response = await httpClient.GetAsync("https://jsonplaceholder.typicode.com/posts/1");
var content = await response.Content.ReadAsStringAsync();

PUT/POST Requests

Use HttpClient to send PUT or POST requests to submit data to a server or update existing resources.

var httpClient = new HttpClient();
var content = new StringContent("{\"title\": \"New Post\", \"body\": \"This is the body of the new post\"}", Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("https://jsonplaceholder.typicode.com/posts", content);
var responseContent = await response.Content.ReadAsStringAsync();

Common Methods and Properties on HttpResponseMessage

Content property

Content.ReadAsStringAsync(): Reads the content of the HTTP response as a string.

var response = await httpClient.GetAsync("https://jsonplaceholder.typicode.com/posts/1");
var content = await response.Content.ReadAsStringAsync();

Content.ReadFromJsonAsync<T>(): Reads the content of the HTTP response and deserializes it to an object of type T.

var response = await httpClient.GetAsync("https://jsonplaceholder.typicode.com/posts/1");
var content = await response.Content.ReadFromJsonAsync<Post>();

Content.ReadAsStreamAsync: Reads the content of the HTTP response as a byte array or stream.

var response = await httpClient.GetAsync("https://jsonplaceholder.typicode.com/posts/1");
var content = await response.Content.ReadAsStreamAsync();

Content.IsSuccessStatusCode: Checks if the HTTP response status code indicates success (status codes 200-299).

var response = await httpClient.GetAsync("https://jsonplaceholder.typicode.com/posts/1");
if (response.IsSuccessStatusCode)
{
    var content = await response.Content.ReadAsStringAsync();
}

EnsureSuccessStatusCode(): this throws an exception if the response status code does not indicate success.

var response = await httpClient.GetAsync("https://jsonplaceholder.typicode.com/posts/1");
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();

🌶️🌶️🌶️ Spencer avoids using this method in most cases, unless the process is some kind of self-healing service where the request will be retried again. Most of the time, I just check IsSuccessStatusCode and handle the error case explicitly.

Usage

Don’t Create One HttpClient per Request: Creating a new HttpClient instance for each request can exhaust system resources. Instead, reuse a single instance.

There are actually better ways to manage HttpClient instances when using HttpClient in the context of an ASP.NET Core application - namely via the IHttpClientFactory abstraction.

Static Shared HttpClient: In older applications or scenarios where resource management is a concern, using a single static instance of HttpClient is considered best practice.

Avoid Disposing HttpClient: Typically, you should avoid disposing of HttpClient instances manually, even though it implements IDisposable. The disposal is managed automatically by the runtime in most cases.