October 21, 2018

Make HttpClient Static in C#

Make HttpClient Static in C#

HttpClient probably is one of the advance http service that Dot Net can offer. It come with rich of features and especially async/await functionality.

Recently I have work on ASP.NET web project required 2 different RESTful API connectors. There will be 2 service endpoint with different credential needed to construct each request, but they both provide exactly same function end point. At first I design the structure.

Structure

* Web Project
* Api Helper
    * Request
        * <everything to construct http request>.cs
    * Response
        * <everything to deserialize http request>.cs
    * Helper
        * Helper.cs
        * AHelperService.cs
        * BHelperService.cs
        * IServiceInterface.cs

The idea is to separate API connector and initialize whenever and wherever we want. The API helper will calling a function that initialize HttpClient instance everytime.

private async Task<HttpResponseMessage> GetRestfulHttpResponse<T>(string requestEndPoint, T requestObject)
{
      var requestStringDictionary = GetStringDictionary(requestObject);

      var uri = $"{restfulEndPoint}{requestEndPoint}";

      FormUrlEncodedContent formEncoded = new FormUrlEncodedContent(requestStringDictionary);
      HttpClient client = new HttpClient();
      client.DefaultRequestHeaders.Add(apiAuthHeaderKey, apiAuthHeaderValue);
      HttpResponseMessage response = await client.PostAsync(uri, formEncoded);

      return response;
}

The structure and function was working well until something wrong was happen. Web server log showing unexpected error captured.

  1. An existing connection was forcibly closed by the remote host
    ex: stackoverflow link
  2. System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
    ex: stackoverflow link

So below is my updated version after googling a lot of articles.

private static readonly HttpClient HttpClient;

static CustomHttpService()
{
    HttpClient = new HttpClient();
}

public async Task<HttpResponseMessage> GetRestfulHttpResponse<T>(T requestObject)
{
    var uri = $"{restfulEndPoint}{requestEndPoint}";

    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri);
    // Add Custom headers here
    //request.Headers.Add(key, value);
    // Add request body content
    //request.Content = formEncoded;
    HttpResponseMessage response = await HttpClient.SendAsync(request);
    response.EnsureSuccessStatusCode();

    Trace.TraceInformation("httpresponse: " + JsonConvert.SerializeObject(response));

    return response;
}

The concept of using HttpService are

  1. You should use only one instance to establish your connection service
  2. You can use static constructor that initialize once only.

After the  update, the issue has been fix completely.