Obtendo conteúdo / mensagem de HttpResponseMessage

175

Estou tentando obter o conteúdo de HttpResponseMessage. Deve ser:, {"message":"Action '' does not exist!","success":false}mas não sei, como tirá-lo do HttpResponseMessage.

HttpClient httpClient = new HttpClient();
HttpResponseMessage response = await httpClient.GetAsync("http://****?action=");
txtBlock.Text = Convert.ToString(response); //wrong!

Nesse caso, o txtBlock teria valor:

StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Vary: Accept-Encoding
  Keep-Alive: timeout=15, max=100
  Connection: Keep-Alive
  Date: Wed, 10 Apr 2013 20:46:37 GMT
  Server: Apache/2.2.16
  Server: (Debian)
  X-Powered-By: PHP/5.3.3-7+squeeze14
  Content-Length: 55
  Content-Type: text/html
}
Clem
fonte

Respostas:

66

Você precisa chamar GetResponse () .

Stream receiveStream = response.GetResponseStream ();
StreamReader readStream = new StreamReader (receiveStream, Encoding.UTF8);
txtBlock.Text = readStream.ReadToEnd();
Icemanind
fonte
33
Obrigado, mas por que obtenho esse erro aqui: "System.Net.Http.HttpResponseMessage 'não contém uma definição para' GetResponseStream 'e nenhum método de extensão' GetResponseStream 'que aceita um primeiro argumento do tipo' System.Net.Http.HttpResponseMessage ' foi encontrado "
Clem
13
@ Klemzy - Porque você está chamando de forma assíncrona. Tente usar a Contentpropriedade. Veja o exemplo aqui . Role para baixo até o segundo passo.
precisa saber é o seguinte
2
@ Klemzy - Veja o exemplo aqui . Role para baixo até o segundo passo. Se você não conseguir descobrir, eu vou editar minha resposta e dar um exemplo para você
Icemanind
17
Esta resposta é totalmente fora de tópico, o OP está usando HttpClient, não HttpWebRequest/ HttpWebResponse.
Maxime Rossini
1
A pergunta é em relação ao HttpCient, sua resposta é baseada no HttpWebRequest desatualizado e obsoleto.
Payam
370

Eu acho que a abordagem mais fácil é mudar a última linha para

txtBlock.Text = await response.Content.ReadAsStringAsync(); //right!

Dessa forma, você não precisa apresentar nenhum leitor de fluxo e nem métodos de extensão.

rudivonstaden
fonte
5
Não sei por que essa não é a resposta aceita, especialmente porque isso permite a você serializar facilmente o conteúdo em seus objetos.
Jason McKindly
3
ReadAsStringAsync não lida bem com erros IMHO.
Stannius
16
Você também pode usar Response.Content.ReadAsStringAsync () Resultado em vez de usar o aguardam.
Justin
8
Cuidado: o ReadAsStringAsync () pode ser lançado se você tiver emoticons ou outros caracteres Unicode na resposta. Eu tive que usar o Streams (como na resposta aceita) para superar isso.
Ginkgo #
41

Tente isso, você pode criar um método de extensão como este:

    public static string ContentToString(this HttpContent httpContent)
    {
        var readAsStringAsync = httpContent.ReadAsStringAsync();
        return readAsStringAsync.Result;
    }

e, em seguida, chame o método de extensão:

txtBlock.Text = response.Content.ContentToString();

Espero que isso lhe ajude ;-)

MCurbelo
fonte
De longe o mais fácil de se levantar e correr
Aage
Use em awaitvez de .Result... ou use um cliente HTTP síncrono, se o seu código não puder lidar com programação assíncrona. Mas qualquer código moderno deve, caso contrário, pode ser um sinal de que seu aplicativo está fazendo algo errado.
Maxime Rossini
9

Se você deseja convertê- lo para um tipo específico (por exemplo, dentro de testes), você pode usar o método de extensão ReadAsAsync :

object yourTypeInstance = await response.Content.ReadAsAsync(typeof(YourType));

ou a seguir para código síncrono:

object yourTypeInstance = response.Content.ReadAsAsync(typeof(YourType)).Result;

Atualização: também existe a opção genérica de ReadAsAsync <> que retorna uma instância de tipo específico em vez da declarada por objeto:

YourType yourTypeInstance = await response.Content.ReadAsAsync<YourType>();
taras-mytofir
fonte
2
objeto yourTypeInstance = aguardar response.Content.ReadAsAsync (typeof (YourType)); deve ser var yourTypeInstance = aguardar response.Content.ReadAsAsync <YourType> ();
Thomas.Benz
Eu usei Request.Content.ReadAsAsync para analisar Json e obtive um desempenho horrível.
21918 W.Leto
4

Pela resposta de rudivonstaden

`txtBlock.Text = await response.Content.ReadAsStringAsync();`

mas se você não quiser fazer o método assíncrono, pode usar

`txtBlock.Text = response.Content.ReadAsStringAsync();
 txtBlock.Text.Wait();`

Wait () é importante, porque estamos executando operações assíncronas e precisamos aguardar a conclusão da tarefa antes de prosseguir.

stanimirsp
fonte
3
usando .Resultqualquer diferente?httpContent.ReadAsStringAsync().Result
mkb
.Resultbloquearia a execução do encadeamento nessa linha ... onde, como txtBlock.Text.Wait()blocos na chamada wait () ... então você está certo de que basicamente não há diferença. Mas eu suspeito txtBlock.Text.Wait()que levaria um parâmetro inteiro opcional para que a GUI não travasse se a ReadAsStringAsync()chamada anterior nunca retornar. Por exemplo, o seguinte seria bloqueado por não mais que 1 segundotxtBlock.Text.Wait(1000)
benhorgen
3

A resposta rápida que sugiro é:

response.Result.Content.ReadAsStringAsync().Result

benhorgen
fonte
NÃO chame Resulttarefas. Você corre o risco de bloquear seu aplicativo. Use async / waitit.
eltiare 14/06
Eu não diria nunca ... às vezes rápido e sujo faz isso. Mas eu concordo que você corre o risco de ReadAsStringAsync()não retornar, portanto, não ligue na GUI ou no encadeamento principal do aplicativo.
benhorgen 15/06
1

Eu acho que a imagem a seguir ajuda para aqueles que precisam aparecer Tcomo o tipo de retorno.

insira a descrição da imagem aqui

snr
fonte
0

Você pode usar o GetStringAsyncmétodo:

var uri = new Uri("http://yoururlhere");
var response = await client.GetStringAsync(uri);
Hinrich
fonte