HTTP Client in Dot Net Core

August 25, 2017

In parallel to the Java/Http Client 4 implementation in the previous post, I also needed to do a call from .NET core in C#.

The endpoint here needs a JSON string posting to it, and it returns JSON back. It's particular about the headers passed - the Content-Type needed correcting in the client (see the references link). It also required HTTP Basic Auth headers to be passed.

This example works fine with a https endpoint.

This code will also show the example of calling through an authenticating proxy, passing a username and password.

Values in this code example that are upper case are constants - replace with values to match what you're trying to call.

Implementation

First we set up the proxy and proxy credentials. There is no default implementation of IWebProxy in dot net core - the one I used is at the bottom of this post.

NetworkCredential proxyCreds = new NetworkCredential(
    PROXY_USERNAME,
    PROXY_PASSWORD,
 );

 WebProxy proxy = new WebProxy(PROXY_URI)
 {
     Credentials = proxyCreds,
 };

We then create our client handler, passing in the proxy.

HttpClientHandler handler = new HttpClientHandler()
{
  Proxy = proxy,
  UseProxy = true,
  PreAuthenticate = true,
  UseDefaultCredentials = false,
};

We can now create a http client and set the basic auth header

HttpClient client = new HttpClient(handler);
var byteArray = Encoding.ASCII.GetBytes($"{USERNAME}:{PASSWORD}");
client.DefaultRequestHeaders.Authorization 
    = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

Next, we create our JSON that we're passing into the service. In this instance, it was a simple structure that took an email address only.

string lCallJson = "{\"email\" : \""+pCallJson.value+"\"}";

StringContent lContent = new StringContent(lCallJson, Encoding.UTF8, "application/json");
lContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

The .NET client by default creates a non-compliant Content-Type header. The last line of the code snippet above fixes this by overwriting the header to just application/json. Without this, the header will contain application/json; charset=utf-8 which caused my service call to fail.

Now we create the message to send, and call through to the endpoint using await.

HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, SERVICE_URL)
{
    Content = lContent,
 };

 HttpResponseMessage response = await client.SendAsync(req);

We can now get the results from the response

HttpContent content = response.Content;
string result = await content.ReadAsStringAsync();

WebProxy

In dot net core, there is no default implementation of IWebProxy, so I had to create my own. The code I used is here:

public class WebProxy : IWebProxy
{
    public WebProxy(string proxyUri) : this(new Uri(proxyUri))
    {
    }

    public WebProxy(Uri proxyUri)
    {
        this.ProxyUri = proxyUri;
    }

    public Uri ProxyUri { get; set; }

    public ICredentials Credentials { get; set; }

    public Uri GetProxy(Uri destination)
    {
        return this.ProxyUri;
    }

    public bool IsBypassed(Uri host)
    {
        return false; /* Proxy all requests */
    }
}

References