HttpClientFactory utilise SocketsHttpHandler comme gestionnaire principal
HttpClientFactory
vous permet de configurer un HttpMessageHandler pipeline pour les objets nommés et typés HttpClient . Le gestionnaire le plus interne, ou celui qui envoie réellement la requête sur le câble, est appelé gestionnaire principal. S’il n’est pas configuré, ce gestionnaire était toujours un HttpClientHandler. Bien que le gestionnaire principal par défaut soit un détail d’implémentation, il y avait des utilisateurs qui en dépendent. Par exemple, certains utilisateurs castent le gestionnaire principal pour HttpClientHandler
définir des propriétés telles que ClientCertificates, UseCookieset UseProxy.
Avec cette modification, le gestionnaire principal par défaut est une SocketsHttpHandler plateforme qui la prend en charge. Sur d’autres plateformes, par exemple .NET Framework, HttpClientHandler continuent d’être utilisées.
SocketsHttpHandler
dispose désormais également de la présélection de propriété PooledConnectionLifetime pour correspondre à la HandlerLifetime valeur. (Elle reflète la dernière valeur, si HandlerLifetime
elle a été configurée par l’utilisateur).
Version introduite
.NET 9 Preview 6
Comportement précédent
Le gestionnaire principal par défaut était HttpClientHandler
. Le cast pour mettre à HttpClientHandler
jour les propriétés s’est produit pour fonctionner.
services.AddHttpClient("test")
.ConfigurePrimaryHttpMessageHandler((h, _) =>
{
((HttpClientHandler)h).UseCookies = false;
});
// This worked.
var client = httpClientFactory.CreateClient("test");
Nouveau comportement
Sur les plateformes où SocketsHttpHandler
il est pris en charge, le gestionnaire principal par défaut est désormais SocketsHttpHandler
défini PooledConnectionLifetime
sur la HandlerLifetime
valeur. Le cast pour mettre à HttpClientHandler
jour les propriétés lève un InvalidCastException.
Par exemple, le même code de la section Précédent du comportement lève désormais un InvalidCastException:
System.InvalidCastException : Impossible de convertir l’objet de type « System.Net.Http.SocketsHttpHandler » en type « System.Net.Http.HttpClientHandler ».
Type de changement cassant
Ce changement est un changement de comportement.
Raison du changement
L’un des problèmes HttpClientFactory
les plus courants rencontrés par les utilisateurs est qu’un ou Typed
un Named
client est capturé par erreur dans un service singleton, ou, en général, stocké quelque part pendant une période plus longue que celle spécifiéeHandlerLifetime. Étant donné que HttpClientFactory
vous ne pouvez pas faire pivoter de tels gestionnaires, ils risquent de ne pas respecter les modifications DNS.
Ce problème peut être atténué à l’aide SocketsHttpHandlerde , qui a une option de contrôle PooledConnectionLifetime. De même que HandlerLifetime, la durée de vie de la connexion mise en pool permet de recréer régulièrement des connexions pour récupérer des modifications DNS, mais à un niveau inférieur. Un client avec PooledConnectionLifetime
configuration peut être utilisé en toute sécurité en tant que singleton.
Malheureusement, il est facile et apparemment « intuitif » d’injecter un Typed
client dans un singleton. Mais il est difficile d’avoir un type de contrôle ou d’analyseur pour s’assurer HttpClient
qu’il n’est pas capturé quand il n’était pas censé être capturé. Il est également difficile de résoudre les problèmes résultants. Ainsi, en tant que mesure préventive , pour réduire l’impact potentiel des modèles d’utilisation erronés, l’atténuation SocketsHttpHandler
est désormais appliquée par défaut.
Cette modification affecte uniquement les cas où le client n’a pas été configuré par l’utilisateur final pour utiliser un fichier personnalisé PrimaryHandler (par exemple, via ConfigurePrimaryHttpMessageHandler<THandler>(IHttpClientBuilder)).
Action recommandée
Il existe trois options pour contourner le changement cassant :
Spécifiez et configurez explicitement un gestionnaire principal pour chacun de vos clients :
services.AddHttpClient("test") .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false });
Remplacez le gestionnaire principal par défaut pour tous les clients à l’aide ConfigureHttpClientDefaults(IServiceCollection, Action<IHttpClientBuilder>)de :
services.ConfigureHttpClientDefaults(b => b.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false }));
Dans l’action de configuration, recherchez à la fois
HttpClientHandler
etSocketsHttpHandler
:services.AddHttpClient("test") .ConfigurePrimaryHttpMessageHandler((h, _) => { if (h is HttpClientHandler hch) { hch.UseCookies = false; } if (h is SocketsHttpHandler shh) { shh.UseCookies = false; } });