Envoyer un message HTTP POST dans ASP.NET Core à l'aide de HttpClient PostAsJsonAsync

143

Je veux envoyer un objet dynamique comme

new { x = 1, y = 2 };

comme corps du message HTTP POST. Alors j'essaye d'écrire

var client = new HttpClient();

mais je ne trouve pas de méthode

client.PostAsJsonAsync()

J'ai donc essayé d'ajouter le package Microsoft.AspNetCore.Http.Extensions à project.json et d'ajouter

using Microsoft.AspNetCore.Http.Extensions; 

to uses clause. Cependant, cela ne m'a pas aidé.

Alors, quel est le moyen le plus simple d'envoyer une requête POST avec un corps JSON dans ASP.NET Core?

Rem
la source
Je
me

Réponses:

206

Vous devez ajouter une référence au package «Microsoft.AspNet.WebApi.Client» (lisez cet article pour des exemples).

Sans aucune extension supplémentaire, vous pouvez utiliser la PostAsyncméthode standard :

client.PostAsync(uri, new StringContent(jsonInString, Encoding.UTF8, "application/json"));

où la jsonInStringvaleur que vous pouvez obtenir en appelantJsonConvert.SerializeObject(<your object>);

Ensemble
la source
1
Mais Microsoft.AspNet.WebApi.Client ne ressemble pas à la bibliothèque ASP.NET Core RC2. Et la deuxième façon est vraiment trop de répétition de code ((
Rem
@Rem pourquoi ne pas créer une HttpClient méthode d'extension ( PostAsJsonAsync) pour utiliser la seconde méthode. Cela vous permet d'éviter la répétition du code.
adem caglin
1
Sûr. Mais j'ai posé la question pour savoir si quelque chose me manque. Je ne peux pas croire qu'il n'a pas encore été implémenté dans Core!
Rem
1
Cette bibliothèque n'est pas une bibliothèque standard / .net, je ne pense pas que System.Net.Http.Formatting ait encore été porté
Chris S
1
Cela fonctionnera pour HttpClient créé par IHttpClientFactory dans .NET Core 2.2 à partir du package nuget Microsoft.Extensions.Http. Cependant, comment procédez-vous de cette manière, mais ajoutez des en-têtes tels qu'une clé d'autorisation.
Nick Gallimore
99

J'utilise cette classe:

public class JsonContent : StringContent
{
    public JsonContent(object obj) :
        base(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json")
    { }
}

Exemple d'utilisation:

new HttpClient().PostAsync("http://...", new JsonContent(new { x = 1, y = 2 }));
stop-cran
la source
5
Pourquoi pas une méthode d'extension? Classe statique publique JsonContent {Tâche publique <?> PostAsJSonAsync (ce client HttpClient, objet toSerializeAsJson) {...}}
TamusJRoyce
2
J'aime l'approche de classe JsonContent
Marco Alves
Est-ce que cela définit l' Content-Length:en-tête HTTP?
Vyacheslav Napadovsky
1
@VyacheslavNapadovsky cela dépend des HttpClientparamètres, par exemple si un ensemble d'en- client.DefaultRequestHeaders.TransferEncodingChunked = true Content-Lengthtête ne serait pas défini et Transfer-Encoding: chunkedserait défini à la place. Cependant, si l'on crée le client comme var client = new HttpClient();, l'en-tête Content-Lengthserait défini pour cette classe de contenu par défaut.
stop-cran
12

J'ajouterais à la réponse acceptée que vous voudriez également ajouter l'en- Accepttête au httpClient:

httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Serj Sagan
la source
oui, pour moi, cela est également nécessaire, confirmé en utilisant le facteur.
Weihui Guo
1

Vous avez raison de dire que cela a été implémenté depuis longtemps dans .NET Core.

Au moment de la rédaction de cet article (septembre 2019), le project.jsonfichier de NuGet 3.x + a été remplacé par PackageReference(comme expliqué sur https://docs.microsoft.com/en-us/nuget/archive/project-json ).

Pour accéder aux *Asyncméthodes de la HttpClientclasse, votre .csprojfichier doit être correctement configuré.

Ouvrez votre .csprojfichier dans un éditeur de texte brut et assurez-vous que la première ligne est
<Project Sdk="Microsoft.NET.Sdk.Web">
(comme indiqué sur https://docs.microsoft.com/en-us/dotnet/core/tools/project-json-to-csproj#the -csproj-format ).

Pour accéder aux *Asyncméthodes de la HttpClientclasse, vous devez également avoir la bonne référence de package dans votre .csprojfichier, comme ceci:

<ItemGroup>
    <!-- ... -->
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <!-- ... -->
</ItemGroup>

(Voir https://docs.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#adding-a-packagereference . Aussi: Nous recommandons les applications ciblant ASP.NET Core 2.1 et utilisez ultérieurement le métapaquet Microsoft.AspNetCore.App , https://docs.microsoft.com/en-us/aspnet/core/fundamentals/metapackage )

Des méthodes telles que PostAsJsonAsync, ReadAsAsync, PutAsJsonAsyncet DeleteAsyncdevraient maintenant fonctionner hors de la boîte. (Aucune directive d'utilisation n'est nécessaire.)

Mise à jour: la balise PackageReference n'est plus nécessaire dans .NET Core 3.0.

Henke
la source
Je n'ai pas réussi à faire fonctionner PostAsJsonAsync avec .NET Core 3.1. Merci
Chris Kolenko