Comment passer un objet à HttpClient?PostAsync et serialize comme un corps JSON?

j'utilise System.Net.Http, j'ai trouvé plusieurs exemples sur le web. J'ai réussi à créer ce code pour faire un POST demande:

public static string POST(string resource, string token)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(baseUri);
        client.DefaultRequestHeaders.Add("token", token);

        var content = new FormUrlEncodedContent(new[]
        {
             new KeyValuePair<string, string>("", "")
        });

        var result = client.PostAsync("", content).Result;
        string resultContent = result.Content.ReadAsStringAsync().Result;
        return resultContent;
    }
 }

tous fonctionne bien. Mais supposons que je veux passer un troisième paramètre à l' POST méthode, un paramètre appelé data. Les données param est un objet comme ceci:

object data = new
{
    name = "Foo",
    category = "article"
};

Comment puis-je faire cela sans créer le <!--6? Mon php RestAPI attendez une entrée json, donc le FormUrlEncodedContent doit envoyer le raw json correctement. Mais comment puis-je faire cela <!--10? Grâce.

43
demandé sur Matthew 2016-04-14 17:15:51

3 réponses

la réponse directe à votre question est: non. La signature pour le PostAsync la méthode est la suivante:

public Task PostAsync (Uri requestUri, HttpContent content)

alors, pendant que vous pouvez passer un objectPostAsync il doit être de type HttpContent et votre type anonyme ne répond pas à ce critère.

cependant, il y a des façons d'accomplir ce que vous voulez accomplir. Tout d'abord, vous aurez besoin de sérialiser votre anonyme de type JSON, l'outil le plus commun pour ce qui est Json.NET. Et le code est assez trivial:

var myContent = JsonConvert.SerializeObject(data);

ensuite, vous devrez construire un objet content pour envoyer ces données, j'utiliserai un ByteArrayContent objet, mais vous pouvez utiliser ou créer un type différent si vous le souhaitez.

var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
var byteContent = new ByteArrayContent(buffer);

ensuite, vous voulez définir le type de contenu pour faire savoir à L'API que C'est JSON.

byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

Ensuite, vous pouvez envoyer votre demande très similaire à votre exemple précédent avec le contenu du formulaire:

var result = client.PostAsync("", byteContent).Result

Sur une note de côté, l'appel de la .Result propriété comme vous le faites ici peuvent avoir certains mauvais effets secondaires comme le verrouillage mort, donc vous voulez être prudent avec cela.

78
répondu CodingGorilla 2016-04-14 14:38:54

vous devez passer vos données dans le corps de la requête comme une chaîne brute plutôt que FormUrlEncodedContent. Une façon de le faire est de sérialiser dans une chaîne JSON:

var json = JsonConvert.SerializeObject(data);

Maintenant tout ce que vous devez faire est de passer la chaîne à la méthode post.

var stringContent = new StringContent(json, UnicodeEncoding.Utf8, "application/json");

var client = new HttpClient();
var response = await client.PostAsync(uri, stringContent);
17
répondu elolos 2018-04-17 16:17:06

Une solution simple est d'utiliser Microsoft ASP.NET Web API 2.2 Client NuGet.

alors vous pouvez simplement faire ceci et il sérialisera l'objet en JSON et définira le Content-Type en-tête application/json; charset=utf-8:

var data = new
{
    name = "Foo",
    category = "article"
};

var client = new HttpClient();
client.BaseAddress = new Uri(baseUri);
client.DefaultRequestHeaders.Add("token", token);
var response = await client.PostAsJsonAsync("", data);
14
répondu trydis 2016-04-14 14:48:33