Element HttpClientFactory używa programu SocketsHttpHandler jako podstawowego programu obsługi
HttpClientFactory
Umożliwia skonfigurowanie potoku HttpMessageHandler dla nazwanych HttpClient i wpisanych obiektów. Najbardziej wewnętrzna procedura obsługi lub ta, która rzeczywiście wysyła żądanie na przewodzie, jest nazywana podstawową procedurą obsługi. Jeśli nie skonfigurowano, ta procedura obsługi była wcześniej zawsze elementem HttpClientHandler. Chociaż domyślna podstawowa procedura obsługi jest szczegółem implementacji, byli użytkownicy, którzy od niego polegali. Na przykład niektórzy użytkownicy rzutować podstawowy program obsługi w celu HttpClientHandler
ustawienia właściwości, takich jak ClientCertificates, UseCookiesi UseProxy.
Dzięki tej zmianie domyślna podstawowa procedura obsługi jest SocketsHttpHandler oparta na platformach, które ją obsługują. Na innych platformach, na przykład .NET Framework, HttpClientHandler nadal jest używany.
SocketsHttpHandler
teraz ma również właściwość wstępnie ustawioną PooledConnectionLifetime , HandlerLifetime aby dopasować wartość. (Odzwierciedla ona najnowszą wartość, jeśli HandlerLifetime
została skonfigurowana przez użytkownika).
Wprowadzona wersja
.NET 9 (wersja zapoznawcza 6)
Poprzednie zachowanie
Domyślna podstawowa procedura obsługi to HttpClientHandler
. Rzutowanie jej w celu HttpClientHandler
zaktualizowania właściwości stało się możliwe.
services.AddHttpClient("test")
.ConfigurePrimaryHttpMessageHandler((h, _) =>
{
((HttpClientHandler)h).UseCookies = false;
});
// This worked.
var client = httpClientFactory.CreateClient("test");
Nowe zachowanie
Na platformach, na których SocketsHttpHandler
jest obsługiwana, domyślna podstawowa procedura obsługi jest teraz SocketsHttpHandler
ustawiona PooledConnectionLifetime
HandlerLifetime
na wartość . Rzutowanie go w celu HttpClientHandler
zaktualizowania właściwości zgłasza błąd InvalidCastException.
Na przykład ten sam kod z poprzedniej sekcji zachowania zgłasza teraz wyjątek InvalidCastException:
System.InvalidCastException: Nie można rzutować obiektu typu "System.Net.Http.SocketsHttpHandler", aby wpisać "System.Net.Http.HttpClientHandler".
Typ zmiany powodującej niezgodność
Ta zmiana jest zmianą behawioralną.
Przyczyna wprowadzenia zmiany
Jednym z najczęstszych problemów HttpClientFactory
, które użytkownicy napotkali, jest to, że klient Named
lub Typed
błędnie zostaje przechwycony w pojedynczej usłudze lub, ogólnie, przechowywane gdzieś przez pewien czas dłuższy niż określony HandlerLifetime. Ponieważ HttpClientFactory
nie można obracać takich procedur obsługi, mogą one nie uwzględniać zmian DNS.
Ten problem można rozwiązać za pomocą polecenia SocketsHttpHandler, który ma opcję kontrolowania PooledConnectionLifetime. Podobnie jak HandlerLifetimew przypadku programu okres istnienia połączenia w puli umożliwia regularne ponowne tworzenie połączeń w celu pobierania zmian DNS, ale na niższym poziomie. Klient z PooledConnectionLifetime
konfiguracją może być bezpiecznie używany jako pojedynczy klient.
Niestety jest to łatwe i pozornie "intuicyjne", aby wstrzyknąć Typed
klienta do pojedynczego. Ale trudno jest mieć jakikolwiek rodzaj sprawdzania lub analizatora, aby upewnić się, że HttpClient
nie jest przechwytywany, gdy nie ma być przechwytywany. Trudno jest również rozwiązać problemy wynikające z tego problemu. W związku z tym jako środek zapobiegawczy — aby zminimalizować potencjalny wpływ błędnych wzorców użycia — SocketsHttpHandler
środki zaradcze są stosowane domyślnie.
Ta zmiana ma wpływ tylko na przypadki, gdy klient nie został skonfigurowany przez użytkownika końcowego do używania niestandardowego PrimaryHandler (na przykład za pośrednictwem polecenia ConfigurePrimaryHttpMessageHandler<THandler>(IHttpClientBuilder)).
Zalecana akcja
Istnieją trzy opcje obejścia zmiany powodującej niezgodność:
Jawnie określ i skonfiguruj podstawową procedurę obsługi dla każdego klienta:
services.AddHttpClient("test") .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false });
Zastąp domyślną podstawową procedurę obsługi dla wszystkich klientów przy użyciu polecenia ConfigureHttpClientDefaults(IServiceCollection, Action<IHttpClientBuilder>):
services.ConfigureHttpClientDefaults(b => b.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false }));
W akcji konfiguracji sprawdź wartości i
HttpClientHandler
SocketsHttpHandler
:services.AddHttpClient("test") .ConfigurePrimaryHttpMessageHandler((h, _) => { if (h is HttpClientHandler hch) { hch.UseCookies = false; } if (h is SocketsHttpHandler shh) { shh.UseCookies = false; } });