Sdílet prostřednictvím


HttpClientFactory používá SocketsHttpHandler jako primární obslužnou rutinu.

HttpClientFactory umožňuje nakonfigurovat HttpMessageHandler kanál pro pojmenované a typované HttpClient objekty. Vnitřní-většina obslužné rutiny, nebo ta, která skutečně odesílá požadavek na drátu, se nazývá primární obslužná rutina. Pokud není nakonfigurovaná, byla tato obslužná rutina dříve vždy .HttpClientHandler I když je výchozí primární obslužná rutina podrobností implementace, byli na ní uživatelé, kteří na ní záviseli. Někteří uživatelé například přetypovávat primární obslužnou rutinu tak, aby HttpClientHandler nastavily vlastnosti, jako ClientCertificatesje , UseCookiesa UseProxy.

Při této změně je výchozí primární obslužná rutina na SocketsHttpHandler platformách, které ji podporují. Na jiných platformách, například rozhraní .NET Framework, HttpClientHandler se nadále používá.

SocketsHttpHandler nyní má také přednastavenou PooledConnectionLifetime vlastnost odpovídající hodnotě HandlerLifetime . (Odráží nejnovější hodnotu, pokud HandlerLifetime ji uživatel nakonfiguroval).

Zavedená verze

.NET 9 Preview 6

Předchozí chování

Výchozí primární obslužná rutina byla HttpClientHandler. Přetypování, aby HttpClientHandler se aktualizovaly vlastnosti, které fungovaly.

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

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

Nové chování

Na platformách, kde SocketsHttpHandler je podporovaná, je teď SocketsHttpHandler výchozí primární obslužná rutina nastavená PooledConnectionLifetime HandlerLifetime na hodnotu. Přetypování na HttpClientHandler aktualizaci vlastností vyvolá výjimku InvalidCastException.

Například stejný kód z předchozí části chování nyní vyvolá InvalidCastException:

System.InvalidCastException: Objekt typu System.Net.Http.SocketsHttpHandler nelze přetypovat na typ System.Net.Http.HttpClientHandler.

Typ zásadní změny

Tato změna je změna chování.

Důvod změny

Jedním z nejběžnějších problémů HttpClientFactory , na které uživatelé narazili, je, když Named se uživatel nebo Typed klient chybně zachytí do jedné služby, nebo obecně uložené někde po dobu delší než zadanou HandlerLifetime. Vzhledem k tomu HttpClientFactory , že takové obslužné rutiny nejde otočit, můžou nakonec nerespektovat změny DNS.

Tento problém lze zmírnit pomocí SocketsHttpHandler, který má možnost řídit PooledConnectionLifetime. HandlerLifetimePodobně jako životnost připojení ve fondu umožňuje pravidelně znovu vytvořit připojení k vyzvednutí změn DNS, ale na nižší úrovni. Klient s nastaveným PooledConnectionLifetime nastavením se dá bezpečně používat jako jednoúčelový.

Je to bohužel snadné a zdánlivě "intuitivní" vložení Typed klienta do jednohotonu. Je ale těžké mít nějaký druh kontroly nebo analyzátoru, aby se zajistilo HttpClient , že se nezachytí, když neměl být zachycen. Je také obtížné vyřešit výsledné problémy. Proto jako preventivní opatření , aby se minimalizoval potenciální dopad chybných vzorů použití, SocketsHttpHandler je teď zmírnění ve výchozím nastavení použito.

Tato změna má vliv pouze na případy, kdy koncový uživatel PrimaryHandler nenakonfiguroval vlastní (například prostřednictvím ConfigurePrimaryHttpMessageHandler<THandler>(IHttpClientBuilder)).

Existují tři možnosti, jak obejít změnu způsobující chybu:

  • Explicitně zadejte a nakonfigurujte primární obslužnou rutinu pro každý z vašich klientů:

    services.AddHttpClient("test")
      .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false });
    
  • Přepište výchozí primární obslužnou rutinu pro všechny klienty pomocí ConfigureHttpClientDefaults(IServiceCollection, Action<IHttpClientBuilder>):

    services.ConfigureHttpClientDefaults(b =>
      b.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false }));
    
  • V akci konfigurace zkontrolujte obě HttpClientHandler možnosti a SocketsHttpHandler:

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

Ovlivněná rozhraní API