次の方法で共有


HttpClientFactory がプライマリ ハンドラーとして SocketsHttpHandler を使用する

HttpClientFactoryでは、名前付きオブジェクトと型指定されたHttpClient オブジェクトのHttpMessageHandler パイプラインを構成できます。 最も内側のハンドラー、または実際にネットワーク上で要求を送信するハンドラーは、 primary ハンドラーと呼ばれます。 構成されていない場合、このハンドラーは以前は常に HttpClientHandlerでした。 既定のプライマリ ハンドラーは実装の詳細ですが、それに依存するユーザーがいました。 たとえば、プライマリ ハンドラーを HttpClientHandler にキャストして、 ClientCertificatesUseCookiesUseProxyなどのプロパティを設定するユーザーもいます。

この変更により、既定のプライマリ ハンドラーは、それをサポートするプラットフォーム上の SocketsHttpHandler です。 他のプラットフォーム (.NET Framework など) では、 HttpClientHandler は引き続き使用されます。

SocketsHttpHandlerには、HandlerLifetime値に一致するPooledConnectionLifetime プロパティ プリセットも追加されました。 ( HandlerLifetime がユーザーによって構成された場合は、最新の値が反映されます)。

導入されたバージョン

.NET 9 Preview 6

以前の動作

既定のプライマリ ハンドラーは HttpClientHandlerされました。 プロパティを更新するために HttpClientHandler にキャストすると、問題が発生しました。

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

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

新しい動作

SocketsHttpHandlerがサポートされているプラットフォームでは、PooledConnectionLifetimeHandlerLifetime値に設定された既定のプライマリ ハンドラーがSocketsHttpHandlerされるようになりました。 プロパティを更新するために HttpClientHandler にキャストすると、 InvalidCastExceptionがスローされます。

たとえば、 Previous 動作 セクションと同じコードが InvalidCastExceptionをスローするようになりました。

System.InvalidCastException: 'System.Net.Http.SocketsHttpHandler' 型のオブジェクトを 'System.Net.Http.HttpClientHandler' 型にキャストできません。

破壊的変更の種類

この変更は、動作変更です。

変更理由

ユーザーが実行 HttpClientFactory 最も一般的な問題の 1 つは、 Named または Typed クライアントがシングルトン サービスで誤ってキャプチャされたとき、または一般に、指定された HandlerLifetimeよりも長い期間、どこかに保存される場合です。 このようなハンドラー HttpClientFactory ローテーションできないため、DNS の変更を考慮しない可能性があります。

この問題は、PooledConnectionLifetimeを制御するオプションがある SocketsHttpHandler を使用して軽減できます。 HandlerLifetimeと同様に、プールされた接続の有効期間では、DNS の変更を取得するために接続を定期的に再作成できますが、レベルは低くなります。 PooledConnectionLifetime設定されたクライアントは、シングルトンとして安全に使用できます。

残念ながら、シングルトンに Typed クライアントを挿入するのは、残念ながら簡単で一見「直感的」です。 しかし、どのような種類のチェックやアナライザーを使用して、 HttpClient がキャプチャされるはずでなかったときにキャプチャされていないことを確認するのは困難です。 また、結果の問題のトラブルシューティングも困難です。 そのため、誤った使用パターンの潜在的な影響を最小限に抑えるための予防措置として、 SocketsHttpHandler 軽減策が既定で適用されるようになりました。

この変更は、クライアントが (たとえば、ConfigurePrimaryHttpMessageHandler<THandler>(IHttpClientBuilder)を使用して) カスタム PrimaryHandlerを使用するようにエンド ユーザーによって構成されていない場合にのみ影響します。

破壊的変更を回避するには、次の 3 つのオプションがあります。

  • 各クライアントのプライマリ ハンドラーを明示的に指定して構成します。

    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