HttpClientFactory maakt gebruik van SocketsHttpHandler als primaire handler
HttpClientFactory
hiermee kunt u een HttpMessageHandler pijplijn configureren voor benoemde en getypte HttpClient objecten. De binnenste handler, of degene die de aanvraag daadwerkelijk op de draad verzendt, wordt een primaire handler genoemd. Als deze handler niet is geconfigureerd, was deze handler voorheen altijd een HttpClientHandler. Hoewel de standaard primaire handler een implementatiedetails is, waren er gebruikers die ervan afhankelijk waren. Sommige gebruikers casten bijvoorbeeld de primaire handler om HttpClientHandler
eigenschappen zoals ClientCertificates, UseCookiesen UseProxy.
Met deze wijziging is de standaard primaire handler een SocketsHttpHandler op platforms die deze ondersteunen. Op andere platforms, bijvoorbeeld .NET Framework, HttpClientHandler wordt nog steeds gebruikt.
SocketsHttpHandler
heeft nu ook de PooledConnectionLifetime vooraf ingestelde eigenschap die overeenkomt met de HandlerLifetime waarde. (Deze weerspiegelt de meest recente waarde, indien HandlerLifetime
geconfigureerd door de gebruiker).
Versie geïntroduceerd
.NET 9 Preview 6
Vorig gedrag
De standaard primaire handler was HttpClientHandler
. Casten om HttpClientHandler
de eigenschappen bij te werken, werkten.
services.AddHttpClient("test")
.ConfigurePrimaryHttpMessageHandler((h, _) =>
{
((HttpClientHandler)h).UseCookies = false;
});
// This worked.
var client = httpClientFactory.CreateClient("test");
Nieuw gedrag
Op platforms waar SocketsHttpHandler
wordt ondersteund, is de standaard primaire handler nu SocketsHttpHandler
ingesteld PooledConnectionLifetime
op de HandlerLifetime
waarde. Casten om HttpClientHandler
de eigenschappen bij te werken genereert een InvalidCastException.
Dezelfde code uit de sectie Vorig gedrag genereert nu bijvoorbeeld een InvalidCastException:
System.InvalidCastException: Kan het object van het type System.Net.Http.SocketsHttpHandler niet casten om 'System.Net.Http.HttpClientHandler' te typen.
Type wijziging die fouten veroorzaken
Deze wijziging is een gedragswijziging.
Reden voor wijziging
Een van de meest voorkomende problemen HttpClientFactory
die gebruikers ondervinden, is wanneer een Named
of Typed
client per ongeluk wordt vastgelegd in een singleton-service, of, in het algemeen, ergens wordt opgeslagen gedurende een bepaalde periode die langer is dan de opgegeven HandlerLifetime. Omdat HttpClientFactory
dergelijke handlers niet kunnen worden geroteerd, kunnen ze mogelijk geen DNS-wijzigingen respecteren.
Dit probleem kan worden verholpen met behulp van SocketsHttpHandler, die een optie heeft om te beheren PooledConnectionLifetime. Net als HandlerLifetimebij de levensduur van de poolverbinding kunnen verbindingen regelmatig opnieuw worden gemaakt om DNS-wijzigingen op te halen, maar op een lager niveau. Een client met PooledConnectionLifetime
set-up kan veilig worden gebruikt als singleton.
Het is helaas gemakkelijk en schijnbaar "intuïtief" om een Typed
client in een singleton te injecteren. Maar het is moeilijk om een soort controle of analyse te hebben om ervoor te zorgen dat HttpClient
deze niet wordt vastgelegd wanneer het niet zou worden vastgelegd. Het is ook moeilijk om de resulterende problemen op te lossen. Als preventieve meting, om de mogelijke impact van onjuiste gebruikspatronen te minimaliseren, wordt de SocketsHttpHandler
beperking nu standaard toegepast.
Deze wijziging is alleen van invloed op gevallen waarin de client niet is geconfigureerd door de eindgebruiker om een aangepaste toepassing PrimaryHandler te gebruiken (bijvoorbeeld via ConfigurePrimaryHttpMessageHandler<THandler>(IHttpClientBuilder)).
Aanbevolen actie
Er zijn drie opties om de wijziging die fouten veroorzaken te omzeilen:
Geef expliciet een primaire handler op en configureer deze voor elk van uw clients:
services.AddHttpClient("test") .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false });
Overschrijf de standaard primaire handler voor alle clients met:ConfigureHttpClientDefaults(IServiceCollection, Action<IHttpClientBuilder>)
services.ConfigureHttpClientDefaults(b => b.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { UseCookies = false }));
Controleer in de configuratieactie op beide
HttpClientHandler
enSocketsHttpHandler
:services.AddHttpClient("test") .ConfigurePrimaryHttpMessageHandler((h, _) => { if (h is HttpClientHandler hch) { hch.UseCookies = false; } if (h is SocketsHttpHandler shh) { shh.UseCookies = false; } });