Como configuro o HttpContent para o meu 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;
}

A PostAsynctoma um outro parâmetro que precisa ser HttpContent.

Como faço para configurar um HttpContent? Não há documentação em nenhum lugar que funcione para o Windows Phone 8.

Se eu fizer GetAsync, funciona muito bem! mas precisa ser POST com o conteúdo de key = "bla", algo = "yay"

//EDITAR

Muito obrigado pela resposta ... Isso funciona bem, mas ainda há algumas dúvidas aqui:

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

Os dados "test = something" que eu assumi pegariam no lado da API como post data "test", evidentemente não. Em outro assunto, talvez seja necessário postar objetos / matrizes inteiros nos dados de postagem, portanto, presumo que o json será o melhor para fazê-lo. Alguma idéia de como eu recebo os dados da postagem?

Talvez 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
fonte

Respostas:

162

Isso é respondido em algumas das respostas para Não é possível encontrar como usar o HttpContent , bem como nesta postagem do blog .

Em resumo, você não pode configurar diretamente uma instância HttpContentporque é uma classe abstrata . Você precisa usar uma das classes derivadas, dependendo da sua necessidade. Provavelmente StringContent, o que permite definir o valor da string da resposta, a codificação e o tipo de mídia no construtor. Consulte: http://msdn.microsoft.com/en-us/library/system.net.http.stringcontent.aspx

Preston Guillot
fonte
2
Vou verificar isso. Acho que quando descobrir isso, vou ter que colocar isso em algum lugar onde todos possam ver! Isso me levou há 4 dias, tentando obter um REST simples para uma API.
Jimmyt1988
O StringContent funcionou muito bem, mas, na verdade, não é possível obter o PostData para acessar o site que estou chamando agora: D. Vou editar a pergunta para mostrar o que eu tenho atualmente
#
2
Uma resposta rápida para "como postar uma representação JSON da minha classe" é "serializar o objeto para JSON, provavelmente com JSON.Net", mas isso realmente pertence a uma pergunta separada.
Preston Guillot
92

Para adicionar à resposta de Preston, aqui está a lista completa das HttpContentclasses derivadas disponíveis na biblioteca padrão:

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/

Também há um suposto, ObjectContentmas não consegui encontrá-lo ASP.NET Core.

Obviamente, você pode pular HttpContenttudo junto com Microsoft.AspNet.WebApi.Clientextensões (você precisará fazer uma importação para que funcione no ASP.NET Core por enquanto: https://github.com/aspnet/Home/issues/1558 ) e então você pode fazer coisas como:

var response = await client.PostAsJsonAsync("AddNewArticle", new Article
{
    Title = "New Article Title",
    Body = "New Article Body"
});
Serj Sagan
fonte
3
Resposta mais abrangente .. maneira muito arrumada e limpa de realizar tarefas aparentemente complicadas.
Salman