首页 > 解决方案 > 如何在自定义 HttpMessageHandler 中设置属性?

问题描述

我正在开发一个跨平台的 Xamarin Forms 应用程序,我希望能够在初始化对象时分别使用特定于平台的HttpMessageHandler子类AndroidClientHandlerNSUrlSessionHandlerHttpClient

为此,我将 Android 和 iOS 应用程序项目配置为使用本机 HTTP 客户端实现,然后使用无参数构造函数进行初始化HttpClient

var client = new HttpClient();

但是,我还想确保消息处理程序的AllowAutoRedirectUseCookies设置为false. 类中没有Handler属性HttpClient。如何确保在隐式初始化的处理程序对象中正确设置了这些处理程序属性?

由于这是跨平台代码,我想尽可能避免使用HttpClient(HttpMessageHandler)构造函数并显式传入特定于平台的处理程序实例。如果可能的话,我希望能够预先配置在无参数构造函数中初始化的处理程序的属性。

编辑

从 API 文档中,很容易得到这样的印象,即如果您将HttpClientHandler对象传递给HttpClient构造函数,将应用特定于平台的处理程序实现:

var handler = new HttpClientHandler
{
  AllowAutoRedirect = false,
  UseCookies = false
};
var client = new HttpClient(handler);

不幸的是,上述方法在实践中不起作用。使用这种方法,HttpClientHandler将实例化一个对象,无论HttpClient在项目设置中是否将实现设置为本地。

理论上,一种替代方法是,如果有任何方法可以获取在无参数构造函数中初始化的处理程序实例,修改它并将修改后的实例传递给HttpMessageHandler参数构造函数,如下所示:

var handler = GetHandlerInstanceAppliedInParameterlessHttpClientConstructor();
handler.AllowAutoRedirect = false;
handler.UseCookies = false;
var client = new HttpClient(handler);

但是,我不知道有任何方法返回这样的处理程序实例。

我还应该指出,我现在主要关心的是 Android,因此主要适用于 Android 的答案可能就足够了。

标签: xamarin.formsxamarin.androiddotnet-httpclient

解决方案


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.


推荐阅读