Comment configurer HttpContent pour mon deuxième paramètre HttpClient PostAsync?

261
public static async Task<string> GetData(string url, string data)
{
    UriBuilder fullUri = new UriBuilder(url);

    if (!string.IsNullOrEmpty(data))
        fullUri.Query = data;

    HttpClient client = new HttpClient();

    HttpResponseMessage response = await client.PostAsync(new Uri(url), /*expects HttpContent*/);

    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    response.EnsureSuccessStatusCode();
    string responseBody = await response.Content.ReadAsStringAsync();

    return responseBody;
}

Le PostAsyncprend un autre paramètre qui doit être HttpContent.

Comment configurer un HttpContent? Il n'y a aucune documentation qui fonctionne pour Windows Phone 8.

Si je le fais GetAsync, cela fonctionne très bien! mais il doit être POST avec le contenu de key = "bla", something = "yay"

//ÉDITER

Merci beaucoup pour la réponse ... Cela fonctionne bien, mais encore quelques incertitudes ici:

    public static async Task<string> GetData(string url, string data)
    {
        data = "test=something";

        HttpClient client = new HttpClient();
        StringContent queryString = new StringContent(data);

        HttpResponseMessage response = await client.PostAsync(new Uri(url), queryString );

        //response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
        response.EnsureSuccessStatusCode();
        string responseBody = await response.Content.ReadAsStringAsync();

        return responseBody;
    }

Les données "test = quelque chose" que je supposais remonteraient du côté de l'api en tant que "données" post-test, ce n'est évidemment pas le cas. Sur un autre sujet, je devrai peut-être publier des objets / tableaux entiers via les données de publication, donc je suppose que json sera le mieux. Avez-vous des idées sur la façon dont je transmets les données des publications?

Peut-être quelque chose comme:

class SomeSubData
{
    public string line1 { get; set; }
    public string line2 { get; set; }
}

class PostData
{
    public string test { get; set; }
    public SomeSubData lines { get; set; }
}

PostData data = new PostData { 
    test = "something",
    lines = new SomeSubData {
        line1 = "a line",
        line2 = "a second line"
    }
}
StringContent queryString = new StringContent(data); // But obviously that won't work
Jimmyt1988
la source

Réponses:

162

Ceci est répondu dans certaines des réponses à Impossible de trouver comment utiliser HttpContent ainsi que dans cet article de blog .

En résumé, vous ne pouvez pas configurer directement une instance de HttpContentcar il s'agit d'une classe abstraite . Vous devez utiliser l'une des classes qui en dérivent en fonction de vos besoins. Très probablement StringContent, ce qui vous permet de définir la valeur de chaîne de la réponse, l'encodage et le type de média dans le constructeur. Voir: http://msdn.microsoft.com/en-us/library/system.net.http.stringcontent.aspx

Preston Guillot
la source
2
Je vais vérifier ça. Je pense que quand je le découvrirai, je vais devoir mettre ça quelque part où tout le monde pourra le voir! Cela me fait aller depuis 4 jours maintenant, essayant d'obtenir un simple REST à une API.
Jimmyt1988
Le StringContent a très bien fonctionné, mais en fait, ne peut pas obtenir les PostData pour accéder au site que j'appelle maintenant: D. Je vais modifier la question pour vous montrer ce que j'ai actuellement
Jimmyt1988
2
Une réponse rapide à «comment publier une représentation JSON de ma classe» est «sérialiser l'objet en JSON, probablement avec JSON.Net», mais cela appartient vraiment à une question distincte.
Preston Guillot du
92

Pour compléter la réponse de Preston, voici la liste complète des HttpContentclasses dérivées disponibles dans la bibliothèque standard:

Crédit: https://pfelix.wordpress.com/2012/01/16/the-new-system-net-http-classes-message-content/

Crédit : https://pfelix.wordpress.com/2012/01/16/the-new-system-net-http-classes-message-content/

Il y a aussi un supposé ObjectContentmais je n'ai pas pu le trouver ASP.NET Core.

Bien sûr, vous pouvez ignorer le tout HttpContentavec des Microsoft.AspNet.WebApi.Clientextensions (vous devrez faire une importation pour le faire fonctionner dans ASP.NET Core pour l'instant: https://github.com/aspnet/Home/issues/1558 ) et ensuite vous pouvez faire des choses comme:

var response = await client.PostAsJsonAsync("AddNewArticle", new Article
{
    Title = "New Article Title",
    Body = "New Article Body"
});
Serj Sagan
la source
3
Réponse la plus complète .. manière très soignée et propre pour réaliser une tâche apparemment compliquée.
salman