Classe System.Net.Http.HttpClient

Cet article vous offre des remarques complémentaires à la documentation de référence pour cette API.

L’instance HttpClient de classe agit comme une session pour envoyer des requêtes HTTP. Une HttpClient instance est une collection de paramètres appliqués à toutes les requêtes exécutées par cette instance. En outre, chaque HttpClient instance utilise son propre pool de connexions, isolant ses requêtes des requêtes exécutées par d’autres HttpClient instances.

Instanciation

HttpClient est destiné à être instancié une fois et réutilisé tout au long de la durée d’une application. Dans .NET Core et .NET 5+, HttpClient regroupe les connexions à l’intérieur de l’instance du gestionnaire et réutilise une connexion entre plusieurs requêtes. Si vous instanciez une classe HttpClient pour chaque requête, le nombre de sockets disponibles sous de lourdes charges sera épuisé. Cette épuisement entraîne SocketException des erreurs.

Vous pouvez configurer des options supplémentaires en transmettant un « gestionnaire », tel que HttpClientHandler (ou SocketsHttpHandler dans .NET Core 2.1 ou version ultérieure), dans le cadre du constructeur. Les propriétés de connexion du gestionnaire ne peuvent pas être modifiées une fois qu’une demande a été envoyée. Par conséquent, une raison de créer une nouvelle instance HttpClient serait si vous devez modifier les propriétés de connexion. Si différentes demandes nécessitent des paramètres différents, cela peut également entraîner la présence d’une application ayant plusieurs HttpClient instances, où chaque instance est configurée de manière appropriée, puis les demandes sont émises sur le client approprié.

HttpClient résout uniquement les entrées DNS lorsqu’une connexion est créée. Il ne suit pas les durées de vie (TTL) spécifiées par le serveur DNS. Si les entrées DNS changent régulièrement, ce qui peut se produire dans certains scénarios de conteneur, le client ne respecte pas ces mises à jour. Pour résoudre ce problème, vous pouvez limiter la durée de vie de la connexion en définissant la propriété SocketsHttpHandler.PooledConnectionLifetime de façon à rendre la recherche DNS obligatoire lorsque la connexion est remplacée.

public class GoodController : ApiController
{
    private static readonly HttpClient httpClient;

    static GoodController()
    {
        var socketsHandler = new SocketsHttpHandler
        {
            PooledConnectionLifetime = TimeSpan.FromMinutes(2)
        };

        httpClient = new HttpClient(socketsHandler);
    }
}

En guise d’alternative à la création d’une seule instance HttpClient, vous pouvez également utiliser IHttpClientFactory pour gérer les instances HttpClient pour vous. Pour plus d’informations, consultez Instructions relatives à l’utilisation de HttpClient.

Dérivation

Il HttpClient agit également en tant que classe de base pour des clients HTTP plus spécifiques. Un exemple serait un FacebookHttpClient qui fournit des méthodes supplémentaires spécifiques à un service web Facebook (par exemple, une GetFriends méthode). Les classes dérivées ne doivent pas remplacer les méthodes virtuelles sur la classe. Utilisez plutôt une surcharge de constructeur qui accepte HttpMessageHandler de configurer tout traitement avant demande ou post-demande.

Transports

Il HttpClient s’agit d’une API de haut niveau qui encapsule les fonctionnalités de bas niveau disponibles sur chaque plateforme où elle s’exécute.

Sur chaque plateforme, HttpClient tente d’utiliser le meilleur transport disponible :

Hôte/runtime BackEnd
Windows/.NET Framework HttpWebRequest
Windows/Mono HttpWebRequest
Windows/UWP Windows natif WinHttpHandler (compatible HTTP 2.0)
Windows/.NET Core 1.0-2.0 Windows natif WinHttpHandler (compatible HTTP 2.0)
Android/Xamarin Sélectionné au moment de la génération. Peut utiliser HttpWebRequest ou être configuré pour utiliser le mode natif d’Android HttpURLConnection
iOS, tvOS, watchOS/Xamarin Sélectionné au moment de la génération. Peut utiliser HttpWebRequest ou être configuré pour utiliser NSUrlSession apple (compatible HTTP 2.0)
macOS/Xamarin Sélectionné au moment de la génération. Peut utiliser HttpWebRequest ou être configuré pour utiliser NSUrlSession apple (compatible HTTP 2.0)
macOS/Mono HttpWebRequest
macOS/.NET Core 1.0-2.0 libcurl- Transport HTTP basé sur HTTP (compatible HTTP 2.0)
Linux/Mono HttpWebRequest
Linux/.NET Core 1.0-2.0 libcurl- Transport HTTP basé sur HTTP (compatible HTTP 2.0)
.NET Core 2.1 et ultérieur System.Net.Http.SocketsHttpHandler

Les utilisateurs peuvent également configurer un transport spécifique en HttpClient appelant le HttpClient constructeur qui prend un HttpMessageHandler.

.NET Framework &Mono

Par défaut, .NET Framework et Mono sont HttpWebRequest utilisés pour envoyer des requêtes au serveur. Ce comportement peut être modifié en spécifiant un autre gestionnaire dans l’une des surcharges du constructeur avec un HttpMessageHandler paramètre. Si vous avez besoin de fonctionnalités telles que l’authentification ou la mise en cache, vous pouvez utiliser WebRequestHandler pour configurer les paramètres et l’instance peut être transmise au constructeur. Le gestionnaire retourné peut être passé à une surcharge de constructeur qui a un HttpMessageHandler paramètre.

.NET Core

À compter de .NET Core 2.1, la System.Net.Http.SocketsHttpHandler classe au lieu de HttpClientHandler fournir l’implémentation utilisée par des classes de mise en réseau HTTP de niveau supérieur telles que HttpClient. L’utilisation d’offres SocketsHttpHandler offre un certain nombre d’avantages :

  • Une amélioration significative des performances par rapport à l’implémentation précédente.
  • L’élimination des dépendances de plateforme, qui simplifie le déploiement et la maintenance. Par exemple, libcurl ne dépend plus de .NET Core pour macOS et .NET Core pour Linux.
  • Comportement cohérent sur toutes les plateformes .NET.

Si cette modification n’est pas souhaitable, sur Windows, vous pouvez continuer à utiliser WinHttpHandler en référençant son package NuGet et en le transmettant manuellement au constructeur de HttpClient.

Configurer le comportement à l’aide des options de configuration du runtime

Certains aspects du comportement sont HttpClientpersonnalisables via les options de configuration runtime. Toutefois, le comportement de ces commutateurs diffère par le biais des versions de .NET. Par exemple, dans .NET Core 2.1 - 3.1, vous pouvez configurer si SocketsHttpHandler elle est utilisée par défaut, mais cette option n’est plus disponible à partir de .NET 5.

Regroupement de connexions

HttpClient met en pool les connexions HTTP si possible et les utilise pour plusieurs requêtes. Cela peut avoir un avantage significatif en matière de performances, en particulier pour les requêtes HTTPS, car la négociation de connexion n’est effectuée qu’une seule fois.

les propriétés du pool d’Connecter ion peuvent être configurées sur un HttpClientHandler ou SocketsHttpHandler transmis pendant la construction, y compris MaxConnectionsPerServer, PooledConnectionIdleTimeoutet PooledConnectionLifetime.

La suppression de l’instance HttpClient ferme les connexions ouvertes et annule les demandes en attente.

Remarque

Si vous envoyez simultanément des requêtes HTTP/1.1 au même serveur, de nouvelles connexions peuvent être créées. Même si vous réutilisez l’instanceHttpClient, si le taux de requêtes est élevé ou s’il existe des limitations de pare-feu, qui peuvent épuiser les sockets disponibles en raison des minuteurs tcp propre up par défaut. Pour limiter le nombre de connexions simultanées, vous pouvez définir la MaxConnectionsPerServer propriété. Par défaut, le nombre de connexions HTTP/1.1 simultanées est illimité.

Mise en mémoire tampon et durée de vie des requêtes

Par défaut, les méthodes HttpClient (sauf GetStreamAsync) mettant en mémoire tampon les réponses du serveur, lisant tout le corps de la réponse en mémoire avant de renvoyer le résultat asynchrone. Ces demandes continuent jusqu’à ce que l’une des opérations suivantes se produise :

Vous pouvez modifier le comportement de mise en mémoire tampon par requête à l’aide du HttpCompletionOption paramètre disponible sur certaines surcharges de méthode. Cet argument peut être utilisé pour spécifier si celui-ci Task<TResult> doit être considéré comme terminé après avoir lu uniquement les en-têtes de réponse, ou après avoir lu et mis en mémoire tampon le contenu de la réponse.

Si votre application qui utilise HttpClient et les classes associées dans l’espace System.Net.Http de noms a l’intention de télécharger de grandes quantités de données (50 mégaoctets ou plus), l’application doit diffuser en continu ces téléchargements et ne pas utiliser la mise en mémoire tampon par défaut. Si vous utilisez la mise en mémoire tampon par défaut, l’utilisation de la mémoire client est très importante, ce qui peut entraîner une réduction substantielle des performances.

Sécurité des threads

Les méthodes suivantes sont thread safe :

Proxies

Par défaut, HttpClient lit la configuration du proxy à partir de variables d’environnement ou de paramètres utilisateur/système, en fonction de la plateforme. Vous pouvez modifier ce comportement en transmettant un WebProxy ou IWebProxy à, dans l’ordre de priorité :

  • Propriété Proxy sur un HttpClientHandler passé pendant la construction de HttpClient
  • La DefaultProxy propriété statique (affecte toutes les instances)

Vous pouvez désactiver le proxy à l’aide UseProxyde . La configuration par défaut pour les utilisateurs Windows consiste à essayer de détecter un proxy à l’aide de la découverte réseau, ce qui peut être lent. Pour les applications à débit élevé où il est connu qu’un proxy n’est pas nécessaire, vous devez désactiver le proxy.

Les paramètres de proxy (comme Credentials) doivent être modifiés uniquement avant la première requête à l’aide de HttpClient. Les modifications apportées après l’utilisation de HttpClient pour la première fois peuvent ne pas être reflétées dans les requêtes suivantes.

Délais d'attente

Vous pouvez utiliser Timeout pour définir un délai d’expiration par défaut pour toutes les requêtes HTTP de l’instance HttpClient. Le délai d’expiration s’applique uniquement aux méthodes xxxAsync qui provoquent l’initialisation d’une demande/réponse. Si le délai d’expiration est atteint, la Task<TResult> demande est annulée.

Vous pouvez définir des délais d’expiration supplémentaires si vous passez dans une SocketsHttpHandler instance lors de la construction de l’objet HttpClient :

Propriété Description
ConnectTimeout Spécifie un délai d’expiration utilisé lorsqu’une demande nécessite la création d’une nouvelle connexion TCP. Si le délai d’expiration se produit, la demande Task<TResult> est annulée.
PooledConnectionLifetime Spécifie un délai d’expiration à utiliser pour chaque connexion dans le pool de connexions. Si la connexion est inactive, la connexion est immédiatement fermée ; sinon, la connexion est fermée à la fin de la requête actuelle.
PooledConnectionIdleTimeout Si une connexion dans le pool de connexions est inactive pendant cette période, la connexion est fermée.
Expect100ContinueTimeout Si la demande a un en-tête « Attendre : 100-continue », il retarde l’envoi du contenu jusqu’à ce que le délai d’expiration ou jusqu’à ce qu’une réponse « 100-continue » soit reçue.

HttpClient résout uniquement les entrées DNS lorsque les connexions sont créées. Il ne suit pas les durées de vie (TTL) spécifiées par le serveur DNS. Si les entrées DNS changent régulièrement, ce qui peut se produire dans certains scénarios de conteneur, vous pouvez utiliser pour PooledConnectionLifetime limiter la durée de vie de la connexion afin que la recherche DNS soit requise lors du remplacement de la connexion.