HttpClientFactory verwendet SocketsHttpHandler als primären Handler
HttpClientFactory
ermöglicht es Ihnen, eine HttpMessageHandler Pipeline für benannte und typierte HttpClient Objekte zu konfigurieren. Der innerste Handler oder der Handler, der die Anforderung tatsächlich an das Kabel sendet, wird als primärer Handler bezeichnet. Wenn sie nicht konfiguriert ist, war dieser Handler zuvor immer ein HttpClientHandler. Während der primäre Standardhandler ein Implementierungsdetails ist, gab es Benutzer, die davon abhängig waren. Beispielsweise wandeln einige Benutzer den primären Handler um, um HttpClientHandler
Eigenschaften wie ClientCertificates, UseCookiesund UseProxy.
Bei dieser Änderung ist der primäre Standardhandler ein SocketsHttpHandler auf Plattformen, die ihn unterstützen. Auf anderen Plattformen, z. B. .NET Framework, HttpClientHandler wird weiterhin verwendet.
SocketsHttpHandler
verfügt nun auch über die Voreinstellung der PooledConnectionLifetime Eigenschaft, um dem HandlerLifetime Wert zu entsprechen. (Er gibt den neuesten Wert wieder, wenn HandlerLifetime
er vom Benutzer konfiguriert wurde).
Eingeführt in Version
.NET 9 Preview 6
Vorheriges Verhalten
Der primäre Standardhandler war HttpClientHandler
. Umwandlung, um HttpClientHandler
die Eigenschaften zu aktualisieren, funktionierten.
services.AddHttpClient("test")
.ConfigurePrimaryHttpMessageHandler((h, _) =>
{
((HttpClientHandler)h).UseCookies = false;
});
// This worked.
var client = httpClientFactory.CreateClient("test");
Neues Verhalten
Auf Plattformen, auf denen SocketsHttpHandler
unterstützt wird, ist der primäre Standardhandler jetzt SocketsHttpHandler
auf PooledConnectionLifetime
den HandlerLifetime
Wert festgelegt. Das Umwandeln, um HttpClientHandler
die Eigenschaften zu aktualisieren, löst ein InvalidCastException.
Beispielsweise löst derselbe Code aus dem Abschnitt "Vorheriges Verhalten " jetzt folgendes aus InvalidCastException:
System.InvalidCastException: Objekt vom Typ 'System.Net.Http.SocketsHttpHandler' kann nicht in den Typ 'System.Net.Http.HttpClientHandler' umwandeln.
Typ des Breaking Changes
Diese Änderung ist eine Verhaltensänderung.
Grund für die Änderung
Eines der häufigsten Probleme, HttpClientFactory
bei denen Benutzer auftreten, besteht darin, dass ein Named
oder Typed
der Client fälschlicherweise in einem Singleton-Dienst erfasst wird oder im Allgemeinen für einen Bestimmten Zeitraum gespeichert wird, der länger als der angegebene HandlerLifetimeZeitraum ist. Da HttpClientFactory
solche Handler nicht gedreht werden können, respektieren sie möglicherweise keine DNS-Änderungen.
Dieses Problem kann mithilfe der Option SocketsHttpHandlerzum Steuern PooledConnectionLifetimeabgemildert werden. Ähnlich wie HandlerLifetimebei der Lebensdauer der poolgebundenen Verbindung können Verbindungen regelmäßig neu aufgebaut werden, um DNS-Änderungen auf einer niedrigeren Ebene aufzunehmen. Ein Client mit PooledConnectionLifetime
Einrichtung kann sicher als Singleton verwendet werden.
Leider ist es einfach und scheinbar "intuitiv", einen Typed
Kunden in ein Singleton einzufügen. Es ist jedoch schwierig, eine Art von Überprüfung oder Analyse zu haben, um sicherzustellen, dass HttpClient
sie nicht erfasst wird, wenn sie nicht erfasst werden soll. Es ist auch schwierig, die resultierenden Probleme zu beheben. Als präventive Maßnahme – um die potenziellen Auswirkungen fehlerhafter Nutzungsmuster zu minimieren – wird die SocketsHttpHandler
Entschärfung jetzt standardmäßig angewendet.
Diese Änderung betrifft nur Fälle, in dem der Client vom Endbenutzer nicht für die Verwendung einer benutzerdefinierten PrimaryHandler (z. B. via ConfigurePrimaryHttpMessageHandler<THandler>(IHttpClientBuilder)) konfiguriert wurde.
Empfohlene Maßnahme
Es gibt drei Optionen zum Umgehen der umbrechenden Änderung:
Geben Sie explizit einen primären Handler für jeden Ihrer Clients an und konfigurieren Sie sie:
services.AddHttpClient("test") .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false });
Überschreiben Sie den primären Standardhandler für alle Clients, die Folgendes verwenden ConfigureHttpClientDefaults(IServiceCollection, Action<IHttpClientBuilder>):
services.ConfigureHttpClientDefaults(b => b.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false }));
Überprüfen Sie in der Konfigurationsaktion auf beide
HttpClientHandler
undSocketsHttpHandler
:services.AddHttpClient("test") .ConfigurePrimaryHttpMessageHandler((h, _) => { if (h is HttpClientHandler hch) { hch.UseCookies = false; } if (h is SocketsHttpHandler shh) { shh.UseCookies = false; } });