IHttpClientFactory,SetBearerToken(),AddHttpClient <>和“您使用的HttpClient错误”

时间:2019-08-23 06:24:23

标签: httpclient httpclientfactory

我敢肯定,我们所有人都读过这篇在2016年引起轰动的文章:https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

对于那些没有的人,总之(强调我的):

  

您不必为每次执行创建新的HttpClient实例,而应在应用程序的整个生命周期内共享一个HttpClient实例。

现在,考虑一个使用HttpClient使用其他Web服务的ASP.NET Core应用程序。其HttpClient的用法可分为两种一般情况:

  1. 未经验证或使用网站自己的凭据的传出请求-在这种情况下,单个HttpClient实际上可以由程序的所有部分共享。

  2. 代表网站当前访问者之一发出的传出请求-或使用特定于请求的凭据的请求。

    • 虽然可以使用单个HttpClient实例 ,但必须注意不要改变其状态,例如,通过设置DefaultRequestHeaders(例如,使用{{ 1}}扩展方法)。

实际上,在ASP.NET Core中使用SetBearerToken的所有指南都指出:

  • 使用类型化的客户端(接受HttpClient实例作为构造函数参数的POCO,以及任何其他DI服务)。
  • 使用HttpClient注册这些类型的客户端。
    • 这会将services.AddHttpClient<TClient>()注册为瞬时实例。
    • 这会将TClient注册为瞬时实例。
    • 这会将ITypedHttpClientFactory<TClient>注册为单个
    • 这会将IHttpClientFactory注册为单个

现在讨论了这个问题,我将引起您的注意:

  • 著名的博客文章-现在是微软自己的文档-说IHttpMessageHandlerFactory实例必须是长寿命的。
  • ASP.NET Core的HttpClient DI系统确实可以确保HttpClient实例是短命的。

但是,如果博客文章确实应该在谈论底层的HttpClient(这是 real HttpClient实现,它被简单包装),那么通过薄壳HttpMessageHandler)-而不是外部class HttpClient

令人困惑的是,人们也报告了使用寿命长的class HttpClient实例的问题,并介绍了其他所有涉及HttpClient的变通办法,这让我感到不舒服:

我的问题:

  • ServicePointManager.FindServicePoint()实例是真的是长寿还是短寿?
  • 还是需要长寿的HttpClient实例?
  • 如果HttpMessageHandlerHttpClient实例具有长寿命:
    • 我如何正确解决两个链接的博客文章中提出的HttpMessageHandler问题?
    • 我是否绝对必须避免使用ServicePointManager,而是在每个HttpClient.DefaultRequestHeaders上显式设置Authorization(Cookies或凭据)标头?还有另一种方法可以减少麻烦吗?
    • 我可以使用自己的HttpRequestMessage添加这些标头吗?那么,这个提议的处理程序的DI注册应该是什么?
  • 如果DelegatingHandler实例(而不是HttpClient实例)是短命的:

    • ...那么可以使用HttpMessageHandler(和HttpClient.DefaultRequestHeaders)吗?
    • 那么SetBearerToken()实例的生存期策略是什么?
    • 我仍然可以使用HttpMessageHandler(和HttpClient.DefaultRequestHeaders)吗?
  • 如果SetBearerToken()实例 HttpClient实例是短命的:

    • 2016年原始博客中提到的问题如何?
      • HttpMessageHandler会采取什么措施来减轻这些问题吗?

0 个答案:

没有答案