¿Cómo configuro HttpContent para mi segundo parámetro 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;
}

El PostAsynctoma otro parámetro que debe ser HttpContent.

¿Cómo configuro un HttpContent? No hay documentación en ningún lugar que funcione para Windows Phone 8.

Si lo hago GetAsync, ¡funciona muy bien! pero debe ser POST con el contenido de key = "bla", something = "yay"

//EDITAR

Muchas gracias por la respuesta ... Esto funciona bien, pero todavía algunas dudas aquí:

    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;
    }

Supuse que la "prueba = algo" de datos se recogería en el lado de la API como "prueba" de datos posteriores, evidentemente no. En otro asunto, es posible que necesite publicar objetos / matrices completos a través de datos de publicación, por lo que supongo que json será lo mejor. ¿Alguna idea sobre cómo obtengo los datos de publicación?

Quizás algo como:

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
fuente

Respuestas:

162

Esto se responde en algunas de las respuestas a No se puede encontrar cómo usar HttpContent , así como en esta publicación de blog .

En resumen, no puede configurar directamente una instancia de HttpContentporque es una clase abstracta . Debe usar una de las clases derivadas de ella según su necesidad. Lo más probable es StringContentque le permite establecer el valor de cadena de la respuesta, la codificación y el tipo de medio en el constructor. Ver: http://msdn.microsoft.com/en-us/library/system.net.http.stringcontent.aspx

Preston Guillot
fuente
2
Voy a ver esto ¡Creo que cuando descubra esto, voy a tener que poner esto en algún lugar donde todos puedan verlo! Esto me ha llevado durante 4 días, tratando de obtener un REST simple para una API.
Jimmyt1988
El StringContent funcionó muy bien, pero en realidad, no puedo hacer que PostData llegue al sitio al que estoy llamando ahora: D.
Editaré la
2
Una respuesta rápida a "¿cómo publico una presentación JSON de mi clase" es "serializar el objeto en JSON, probablemente con JSON.Net", pero eso realmente pertenece a una pregunta separada.
Preston Guillot
92

Para agregar a la respuesta de Preston, aquí está la lista completa de las HttpContentclases derivadas disponibles en la biblioteca estándar:

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

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

También hay un supuesto, ObjectContentpero no pude encontrarlo ASP.NET Core.

Por supuesto, puede omitir HttpContenttodo junto con Microsoft.AspNet.WebApi.Clientextensiones (tendrá que hacer una importación para que funcione en ASP.NET Core por ahora: https://github.com/aspnet/Home/issues/1558 ) y luego puedes hacer cosas como:

var response = await client.PostAsJsonAsync("AddNewArticle", new Article
{
    Title = "New Article Title",
    Body = "New Article Body"
});
Serj Sagan
fuente
3
La respuesta más completa ... una forma muy ordenada y limpia de lograr una tarea aparentemente complicada.
salman