I am developing a cross-platform Xamarin Forms app, and I want to be able to use the platform-specific HttpMessageHandler
subclasses AndroidClientHandler
and NSUrlSessionHandler
respectively, when I initialize the HttpClient
object.
To accomplish this, I am configuring the Android and iOS app projects to use native HTTP client implementations, and then I use the parameterless constructor to initialize HttpClient
:
var client = new HttpClient();
However, I also would like to ensure that AllowAutoRedirect
and UseCookies
of the message handler are set to false
. There is no Handler
property in the HttpClient
class. How can I ensure that these handler properties are correctly set in the implicitly initialized handler objects?
Since this is cross-platform code, I would like to avoid as much as possible to resort to using the HttpClient(HttpMessageHandler)
constructor and explicitly pass in platform-specific handler instances. If at all possible, I would like to be able to pre-configure the properties of the handlers that are initialized in the parameterless constructor.
EDIT
From API documentation, it is easy to get the impression that the platform-specific handler implementations will be applied if you pass a HttpClientHandler
object to the HttpClient
constructor:
var handler = new HttpClientHandler
{
AllowAutoRedirect = false,
UseCookies = false
};
var client = new HttpClient(handler);
Unfortunately, the above does not work in practice. With this approach, a HttpClientHandler
object will be instantiated, regardless of whether HttpClient
implementation has been set to native in the project settings.
In theory, one alternative would be if there was any way to obtain an instance of the handler that is initialized in the parameterless constructor, modify it and pass the modified instance into the HttpMessageHandler
argument constructor, something like this:
var handler = GetHandlerInstanceAppliedInParameterlessHttpClientConstructor();
handler.AllowAutoRedirect = false;
handler.UseCookies = false;
var client = new HttpClient(handler);
However, I am not aware of any method returning such a handler instance.
I should also point out that my main concern right now is Android, so an answer that applies primarily to Android might be enough.
You don't need to expose the native handlers and implement it for both platforms. HttpClient
accepts an overload with a handler, like you stated. However, that handler is a .NET Standard handler. So, if you initialise the handler in the shared project, or inherit from it in the native ones, they are the same type of class.
In your shared project, you can simply initialise the client like this:
var handler = new HttpClientHandler
{
AllowAutoRedirect = false,
UseCookies = false
};
var client = new HttpClient(handler);
However, this way you will override the "native" handler and will use HttpClientHandler instead.
Additional remarks, based on comments and edited question:
To answer your question - no, there isn'y any built-in way to get the AndroidClientHandler
in the shared code. You'll have to expose it yourself. You can also write your own native handlers and expose them through a DependencyService
and then invoke the ctor with them. The latter I have done in the past and it worked with no issues.