Create Generic HttpClient Call Function With Error Handling In C#

In today's world of software development, making HTTP requests to external APIs is a common requirement. In C#, the HttpClient class provides a simple way to make HTTP requests, but writing the same boilerplate code for every API call can become repetitive and error-prone. In this article, we'll show you how to create a generic HttpClient call function in C# that can handle different request methods, request body types, response types, and error handling using optional parameters.

Creating the Generic HttpClient Call Function

Let's start by creating a generic function that can handle different request methods, request body types, and response types,

using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
public async Task < TResponse > MakeHttpRequestAsync < TRequest, TResponse > (string url, HttpMethod httpMethod, TRequest requestBody =
    default, bool handleErrors = false) {
    using(var client = new HttpClient()) {
        var request = new HttpRequestMessage {
            Method = httpMethod,
                RequestUri = new Uri(url)
        };
        if (requestBody != null) {
            var json = JsonSerializer.Serialize(requestBody);
            request.Content = new StringContent(json, Encoding.UTF8, "application/json");
        }
        var response = await client.SendAsync(request);
        if (handleErrors && !response.IsSuccessStatusCode) {
            throw new HttpRequestException($ "HTTP request failed with status code {response.StatusCode}");
        }
        var responseJson = await response.Content.ReadAsStringAsync();
        var responseData = JsonSerializer.Deserialize < TResponse > (responseJson);
        return responseData;
    }
}

Let's take a closer look at the parameters and how they work,

  • TRequest: the type of the request body. This can be any serializable type, such as a class or struct.
  • TResponse: the type of the expected response. This can also be any serializable type.
  • url: the URL to send the HTTP request to.
  • httpMethod: the HTTP method to use, such as HttpMethod.Get or HttpMethod.Post.
  • requestBody (optional): the request body to send with the request. This can be null if no request body is required.
  • HandleErrors (optional): a boolean value indicating whether to throw an exception if the HTTP request fails. The default value is false.

In the function body, we first create a new HttpClient instance and an HttpRequestMessage with the specified URL and HTTP method. If a request body is provided, we serialize it to JSON and set it as the content of the HttpRequestMessage.

Next, we send the request using HttpClient.SendAsync. If throwsExceptionOnError is true and the response code indicates an error, we throw a HttpRequestException with the status code.

Finally, we read the response content as a string using HttpContent.ReadAsStringAsync, deserialize the response JSON into the specified TResponse type using JsonSerializer.Deserialize, and return the deserialized response data.

Conclusion

In this article, we've shown you how to create a generic HttpClient call function in C# that can handle different request methods request body types, response types, and error handling using optional parameters. Using this function saves time and reduces the risk of errors when making HTTP requests to external APIs in your C# applications.