共用方式為


HttpClientFactory 使用 SocketsHttpHandler 作為主要處理程式

HttpClientFactory 可讓您 HttpMessageHandler 設定具名和具型別 HttpClient 物件的管線。 最內部的處理程式,或實際在線路上傳送要求的處理程式,稱為 主要處理程式。 如果未設定,則此處理程式先前一律為 HttpClientHandler。 雖然預設的主要處理程式是實作詳細數據,但有使用者相依於此。 例如,某些使用者會將主要處理程序轉換成 ,HttpClientHandler以設定、 UseCookiesUseProxyClientCertificates屬性。

透過這項變更,預設的主要處理程式是在 SocketsHttpHandler 支援它的平臺上。 在其他平臺上,例如.NET Framework 會 HttpClientHandler 繼續使用。

SocketsHttpHandler 現在也具有 PooledConnectionLifetime 屬性預設以符合 HandlerLifetime 值。 (如果 HandlerLifetime 已由用戶設定,則會反映最新的值)。

導入的版本

.NET 9 Preview 6

先前的行為

預設的主要處理程式為 HttpClientHandler。 將它 HttpClientHandler 轉換成 以更新屬性時發生工作。

services.AddHttpClient("test")
    .ConfigurePrimaryHttpMessageHandler((h, _) =>
    {
        ((HttpClientHandler)h).UseCookies = false;
    });

// This worked.
var client = httpClientFactory.CreateClient("test");

新的行為

在支援的平臺上SocketsHttpHandler,預設的主要處理程式現在SocketsHttpHandlerPooledConnectionLifetime已設定為 HandlerLifetime 值。 將它 HttpClientHandler 轉換成 以更新屬性會擲回 InvalidCastException

例如,先前行為區段中的相同程式代碼現在會InvalidCastException擲回 :

System.InvalidCastException:無法將類型為 'System.Net.Http.SocketsHttpHandler' 的物件轉換成類型 'System.Net.Http.HttpClientHandler'。

中斷性變更的類型

此變更為行為變更

變更原因

使用者遇到的其中一個最常見問題 HttpClientFactory ,就是 Named 在單一服務中錯誤地擷取 或 Typed 用戶端時,或一般而言,儲存在某處一段時間的時間超過指定的 HandlerLifetime。 因為 HttpClientFactory 無法輪替這類處理程式,所以它們最終可能不會遵守 DNS 變更。

使用 SocketsHttpHandler可以減輕此問題,其有可控制 PooledConnectionLifetime的選項。 同樣地 HandlerLifetime,集區連線存留期允許定期重新建立連線以挑選 DNS 變更,但在較低層級。 已設定的 PooledConnectionLifetime 用戶端可以安全地當做單一使用。

不幸的是,將用戶端插入 Typed 單一用戶端是簡單且看似「直覺」的。 但是很難有任何類型的檢查或分析器,以確保 HttpClient 在不應該被擷取時不會擷取。 也很難針對產生的問題進行疑難解答。 因此,作為預防性措施,為了將錯誤使用模式的潛在影響降到最低, SocketsHttpHandler 風險降低現在預設會套用。

這項變更只會影響使用者未將客戶端設定為使用自定義 PrimaryHandler 的案例(例如透過 ConfigurePrimaryHttpMessageHandler<THandler>(IHttpClientBuilder))。

有三個選項可以解決重大變更:

  • 明確指定並設定每個用戶端的主要處理程式:

    services.AddHttpClient("test")
      .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false });
    
  • 使用 ConfigureHttpClientDefaults(IServiceCollection, Action<IHttpClientBuilder>)覆寫所有客戶端預設主要處理程式:

    services.ConfigureHttpClientDefaults(b =>
      b.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false }));
    
  • 在組態動作中,檢查 HttpClientHandlerSocketsHttpHandler

    services.AddHttpClient("test")
      .ConfigurePrimaryHttpMessageHandler((h, _) =>
      {
          if (h is HttpClientHandler hch)
          {
              hch.UseCookies = false;
          }
    
          if (h is SocketsHttpHandler shh)
          {
              shh.UseCookies = false;
          }
      });
    

受影響的 API