Xamarin.Forms Native HttpClientHandler for HttpClient…

Let’s make sure our Xamarin.Forms apps are properly configured with Native HttpClientHandler for optimum performance and better network security..

If you’re using the HttpClient for making Web API calls outside your app, you probably using the HttpClientHandler to set up various kinds of configuration for the HttpClient instance.

Now this HttpClient and Native HttpClientHandler applies directly for both Xamarin Native and Xamarin.Forms apps…

Although in this article I’m focusing on Xamarin.Forms, the same configuration set up can be used for any Xamarin Native apps as well.  By default in Xamarin you can use either the Managed HttpClientHandler which is fully maintained by .NET mono run time or the Native HttpClientHandler that maps itself to the Native run time configuration.

Why Native HttpClientHandler?

Thanks to the awesomeness of the Xamarin and the powerful Xamarin.Forms ability to map itself efficiently to the Native device environment, provides you with this facility to use the device Native Network Layer’s configuration in your Apps as well.

  • Using the Native HttpClientHandler provides you with a lot of advantages in terms of Network Communication Layer, which maps itself completely to the native properties and behaviors.
  • It provides your App with the in built default System native Security such as Transport Layer Security, TLS 1.2 features. This is basically built in for both Android and iOS system devices by default, which then we can leverage automatically on to our Xamarin.Forms app as well during run time.
  • This gives the user a peace of mind, in terms of the security of the network communication in the app while also giving the user the free of choice to let the app inherit itself the system configured security settings.
  • Defaulting to the Native Network configuration we can make sure our app is fine tuned for Security and Performance on the device native level and you do not have to spend extra time managing those bits manually.
  • Another great advantage is not needing to manually handle device Proxy Settings, allowing your Xamarin.Forms app to communicate through the device’s default network tunnel.

Well that’s pretty much a good list of reasons to make sure to set up our Xamarin.Forms apps to use the Native HttpClientHandlers eh! 😉

So what are they?

So below are the Native HttpClientHandlers available in Xamarin run time for each Platform, which applies for Xamarin.Forms as well.

AndroidClientHandler -AndroidClientHandler is the new handler that delegates to native Java code and Android OS instead of implementing everything in managed code. This option has better performance and smaller executable size.

NSUrlSessionHandler -The NSURLSession-based handler is based on the native NSURLSession framework available in iOS 7 and newer. This options has better performance and smaller executable size, supports TLS 1.2 standard.

WinHttpHandler -WinHttpHandler is implemented as a thin wrapper on the WinHTTP interface of Windows and is only supported on Windows systems. Provides developers with more granular control over the application’s HTTP communication than the default HttpClientHandler class.

So here as you can see, using the device native HttpClientHandlers provides you with the best of performance and security for your app compared to opting to use the Managed HttpClientHandler where you have to manually handle those optimizations yourself.

Although I must make a note here, in Windows or UWP Xamarin apps the default set up is the .NET Managed HttpClientHandler because the underlying native environment is Windows itself. But opting to use WinHttpHandler provides arguably better advantage according to many documentation, and also it’s in the same .NET stack! 😉

What no to do?

So before we get into “the how?”, let’s first make sure the bits not to do in our app project!

– not use “Managed”

So when it comes to Xamarin.Forms, by default when you create your project in Visual Studio the Native project nodes Properties are set up to use the Native HttpClient Handlers already. You can see this in both Android and iOS Project settings,

  • Android project node -> Properties -> Android Options -> Click “Advanced”
  • iOS project node -> Properties -> iOS Build

Do not set it to option to “Managed” HttpClientHandler in either of those settings, which will opt you out of Native HttpClientHandler.

– not use “new HttpClientHanlder()” 

If the above Settings check success, the next thing to consider is not instantiating HttpClientHanlder on its own as below,

HttpClientHandler httpClientHandler = new HttpClientHandler();
...
// setting up httpClientHandler settings
...
...
HttpClient httpClient = new HttpClient(httpClientHandler);

 

This is something you should not do, which will override your Native project property set up regarding the HttpClientHandler, and opt your HttpClient to use Managed HttpClientHandler instead, resulting you losing all the native goodness!

Next let’s see what to do?

What to do?

Here are the things you need to make sure to do instead.

– not using HttpClientHandler!?

Consider not using HttpClientHandler at all with your HttpClient, then you’re basically good to go, as long as you have set it up in your App Project Native settings. Not a joke though! lol 😛

Just use plain HttpClient instance out of the box! but make sure to do the following as well.

– set Native HttpClientHandler!

Go to the following settings in each of your Xamarin.Forms Native project nodes,

  • Android project node -> Properties -> Android Options -> Click “Advanced”

  • iOS project node -> Properties -> iOS Build

Make sure to set the Native Android and NSUrlSessionHandler those settings, to opt to use AndroidClientHandler and iOS NSUrlSessionHandler for your HttpClientHandler by default.

Well UWP or Windows project nodes doesn’t have such settings as it by defaults use .NET Managed HttpClientHandler.

A little demo!

Now if its all good, you should be able to see the following behaviors in action,

So this is a little Xamarin.Forms demo that I prepared to demonstrate the behaviors of Native HttpClientHandlers on Android, iOS and Windows UWP.

Here I’m demonstrating the Network access (blue color access granted and red color access blocked in run time) for a list of scenarios,

Now you can see how each device Native environment handles those endpoint calls, basically only allowing access to trusted secure web endpoints in the native network tunnel to go through.

Well that was quite simple eh! but we all know the real life requirements wouldn’t be so simple, what if we need to use the HttpClientHandler in code?

Yes we need access to the Native HttpClientHandler in code!

So then let me walk you through handling an advance implementation of the native HttpClientHandler with more customization added in code! 😉 

How to? Advanced set up of Native HttpClientHandler!

Yes as you can see in the Project Settings, it doesn’t really give you much options to customize your Native HttpClientHandler settings, or even override some of its behaviors at all. In a real life scenarios you would definitely need some more access to your HttpClientHandler use in code.

Compared to the Managed .NET HttpClientHandler where you easily have access to all its properties and behaviors.

But it is crucial for us to stick to the Native HttpClientHandler, so the solution would be to implement an access to the Native HttpClientHandler in our Xamarin.Forms code.

– Under the hood!?

Thanks to the awesomeness of Xamarin we have full access to those Native HttpClientHandlers in code as well, so that we can use them as however as we like. Let’s take a look under the hood of these Native bits shall we,

Android:

iOS:

Windows:

Now you can see that all these Native Handlers are extending from either HttpClientHandler or the HttpMessageHandler,

Drilling down further into HttpClientHandler we can see that its extending itself from HttpMessageHandler.

– Using em in code!

Let’s start by using our AndroidClientHandler in code to be used with HttpClient instance.

var androidClientHandler = new AndroidClientHandler();
... 
// setting up native httpClientHandler settings
...
...
HttpClient httpClient = new HttpClient((HttpMessageHandler)androidClientHandler);

 

And for iOS with the NSUrlSessionHandler.

var iosClientHandler = new NSUrlSessionHandler();
... 
// setting up native httpClientHandler settings
...
...
HttpClient httpClient = new HttpClient((HttpMessageHandler)iosClientHandler);

 

Then for Windows or UWP, opt to our WinHttpHandler.

var uwpClientHandler = new WinHttpHandler();
... 
// setting up native httpClientHandler settings
...
...
HttpClient httpClient = new HttpClient((HttpMessageHandler)uwpClientHandler);

On Windows or UWP make sure to install nuget package: System.Net.Http.WinHttpHandler to use WinHttpHandler which is a far better native option than default HttpClientHandler.

As you can see we’re casting them to HttpMessageHandler as a common ground object, since they all inherit from that base.

Now that we’ve got access to them in code, we can access all their properties and behaviors, and even override to customize them as we wish to.

– build the bridge to Xamarin.Forms!

Since the above bits are not directly accessible from Xamarin.Forms, we need to build the bridge that will allow us to access the Native HttpClientHandler instance in Xamarin.Forms environment directly.

Since I already created a common ground instance across all the native environments with the casting to HttpMessageHandler, this is much easier. Now there are plenty of ways leverage the access to this object up towards Xamarin.Forms layer, but here I’m going to showcase rather a simple implementation.

code on github repo: XFNativeHttpClientHandler/Services/HttpClientService.cs

Here I have a simple Service implementation in Xamarin.Forms where it maintains a Singleton object of itself, which contains a HttpClient object and HttpClientHandler object.

Given the HttpClientHandler is provided, I am instantiating my HttpClient() on demand during the run time as you can see below.

private HttpClientService()
{
    HttpClient = HttpClientHandler != null ?
        new HttpClient((HttpMessageHandler)HttpClientHandler) 
      : new HttpClient();
}

public static HttpClientService Instance
{
    get
    {
        lock (Padlock)
        {
            return _instance ?? 
                  (_instance = new HttpClientService());
        }
    }
}

 

So the setting up of the HttpClientHandler property happens in the each Native level’s execution start up point.

On Android: MainActivity.cs

protected override void OnCreate(Bundle savedInstanceState)
{
    ...
    
    var androidClientHandler = new HttpClientHandler();
    Services.HttpClientService.HttpClientHandler =               
                                     androidClientHandler;
    
    ...
}

 

On iOS: AppDelegate.cs

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    ...
    
    var iosClientHandler = new NSUrlSessionHandler();
    Services.HttpClientService.HttpClientHandler = iosClientHandler;

    ...
}

 

On Windows (UWP): MainPage.xaml.cs

public MainPage()
{
    ...

    var uwpClientHandler = new WinHttpHandler();
    Services.HttpClientService.HttpClientHandler = uwpClientHandler;

    ...
}

 

That’s it for the set up, then let’s use it in Xamarin.Forms code:

var result = await HttpClientService.Instance.
		HttpClient.GetAsync("https://google.com/");

 

Now this should provide you with a Xamarin.Forms Solution allowing you to be able to access all the Properties and Behaviors of Native HttpClientHandlers!

Yay! Access in Code!

So the whole point of access these Native HttpClientHandlers in code was to be able to customize their settings and behaviors according to our requirements eh! 😀

Go ahead and access those properties and behaviors that you wish to use…

Here’s me demonstrate a simple scenario, how to override HTTPS Certificate Validation while using our Native HttpClientHandlers!

Full gist: https://gist.github.com/UdaraAlwis/0787f74796d22c294b91be81ff162347

Things Keep in mind!

So when you’re accessing the Native HttpClientHandlers in code there are some things you need to absolutely keep in your mind, to make sure the performance and security is not compromised.

– Custom bits, only Native level!

All the custom configuration that you need to do should be done in Native Xamarin level code, accordingly to native properties and behaviors.

– One time init() only!

You should instantiate your Native HttpClientHandler instances from Native level only once, and they shouldn’t be altered later for consistency during run time across your app.

– HttpMessageHandler, keep it as it is!

Keep the HttpMessageHandler instance that we up-cast from the Native HttpClientHandler instances as it is after instantiation, to make sure you’re not overriding any native properties and behaviors that we set up or inherited prior.

– Release Build, watch out!

When you’re using the Xamarin Platform specific Project Settings, make sure those settings are propagated to Release mode as well. In .csproj file has separate configurations for Debug and Release build configurations, so make sure keep an eye out for those configuration during Release builds as well.

Conclusion

Whenever you need to use the HttpClientHandler along side HttpClient, in your Xamarin.Forms or Native Xamarin Apps, its best to use the Native HttpClientHandler. This can be easily configured in each Native Project Settings or we can even instantiate them in code to be used across our Xamarin.Forms app environment as I’ve explained in this article.

I have shared the demo app code in my github as usual: github.com/XFNativeHttpClientHandler

Well that’s it! 😉

Share the love! Cheers!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.