web-dev-qa-db-fra.com

Est-il possible pour HttpClient d'envoyer du contenu ou un corps pour une demande GET?

Actuellement, pour envoyer une requête GET paramétrée à une interface API, j'écris le code suivant:

api/master/city/filter?cityid=1&citycode='ny'

Mais je vois qu'il y a une limite à la longueur d'URL de 2 083 caractères.

Pour éviter cela, je voudrais envoyer les paramètres au format json dans le corps du contenu pour une demande GET.

Cependant, je vois qu'aucune des méthodes Get pour HttpClient ne permet d'envoyer un corps de contenu. Pour le POST j'ai pu voir qu'il y a une méthode dans HttpClient nommée PostAsync qui permet un corps de contenu.

Existe-t-il un moyen d'envoyer des paramètres pour une demande GET ne figurant pas dans l'URL afin d'éviter la limite de longueur d'URL?

14
John

Veuillez lire les avertissements à la fin de cette réponse pour savoir pourquoi les requêtes HTTP GET avec des corps ne sont généralement pas conseillées.


  • Si vous utilisez .NET Core , le standard HttpClient peut le faire tout de suite boîte. Par exemple, pour envoyer une demande GET avec un corps JSON:

    HttpClient client = ...
    
    ...
    
    var request = new HttpRequestMessage
    {
        Method = HttpMethod.Get,
        RequestUri = new Uri("some url"),
        Content = new StringContent("some json", Encoding.UTF8, ContentType.Json),
    };
    
    var response = await client.SendAsync(request).ConfigureAwait(false);
    response.EnsureSuccessStatusCode();
    
    var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
    
  • .NET Framework ne prend pas en charge ce prêt-à-l'emploi (vous recevrez un ProtocolViolationException si vous essayez le code ci-dessus ). Heureusement, Microsoft a fourni le package System.Net.Http.WinHttpHandler qui le fait prend en charge la fonctionnalité - installez et utilisez-le simplement au lieu de la valeur par défaut HttpClientHandler lors de la construction de vos instances HttpClient:

    var handler = new WinHttpHandler();
    var client = new HttpClient(handler);
    
    <rest of code as above>
    

    Référence: https://github.com/dotnet/corefx/issues/28135#issuecomment-467261945


Mises en garde:

  • HTTP GET avec un corps est une construction quelque peu non conventionnelle qui tombe dans une zone grise de la spécification HTTP - le résultat final est que de nombreux logiciels plus anciens ne peuvent pas du tout gérer une telle demande, ou la rejetteront explicitement parce qu'ils le croient être mal formé. Vous devez vous assurer que le point de terminaison auquel vous essayez d'envoyer une telle demande la prend en charge, ou au mieux, vous obtiendrez un code d'erreur HTTP; au pire, le corps sera jeté en silence. Cela peut conduire à un débogage effrayant!
  • La mise en cache des serveurs proxy, en particulier les plus anciens, peut mettre en cache les demandes GET basées uniquement sur l'URL car ils ne s'attendent pas à ce qu'un corps soit présent. Cela peut entraîner la mise en cache définitive de la demande la moins récente (ce qui cassera votre logiciel) ou la seule demande jamais mise en cache est la plus récente émise (ce qui empêchera la mise en cache de fonctionner comme prévu). Encore une fois, cela peut être très douloureux à comprendre.
20
Ian Kemp