Obtener contenido / mensaje de HttpResponseMessage

175

Estoy tratando de obtener contenido de HttpResponseMessage. Debería ser: {"message":"Action '' does not exist!","success":false}pero no sé cómo sacarlo de HttpResponseMessage.

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

En este caso, txtBlock tendría 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
}
Ayunarse
fuente

Respuestas:

66

Debe llamar a GetResponse () .

Stream receiveStream = response.GetResponseStream ();
StreamReader readStream = new StreamReader (receiveStream, Encoding.UTF8);
txtBlock.Text = readStream.ReadToEnd();
Icemanind
fuente
33
Gracias, pero por qué recibo este error aquí: "System.Net.Http.HttpResponseMessage 'no contiene una definición para' GetResponseStream 'y ningún método de extensión' GetResponseStream 'que acepte un primer argumento de tipo' System.Net.Http.HttpResponseMessage ' podría ser encontrado "
Clem
13
@Klemzy: porque lo estás llamando de forma asincrónica. Intenta usar la Contentpropiedad en su lugar. Mira el ejemplo aquí . Desplácese hasta el segundo paso.
Icemanind
2
@Klemzy - Mira el ejemplo aquí . Desplácese hasta el segundo paso. Si no puede resolverlo,
editaré
17
Esta respuesta está totalmente fuera de tema, el OP está usando HttpClient, no HttpWebRequest/ HttpWebResponse.
Maxime Rossini
1
La pregunta es con respecto a HttpCient, su respuesta se basa en HttpWebRequest obsoleto y obsoleto.
Payam
371

Creo que el enfoque más fácil es cambiar la última línea a

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

De esta manera, no necesita introducir ningún lector de flujo y no necesita ningún método de extensión.

rudivonstaden
fuente
55
No estoy seguro de por qué esta no es la respuesta aceptada, especialmente porque le brinda la capacidad de serializar fácilmente los contenidos en sus objetos.
Jason McKindly
3
ReadAsStringAsync no maneja bien los errores en mi humilde opinión.
stannius
16
También puede usar Response.Content.ReadAsStringAsync (). Resultado en lugar de usar wait
Justin
8
Sin embargo, tenga cuidado: ReadAsStringAsync () puede arrojar si tiene emoticones u otros caracteres Unicode en la respuesta. Tuve que usar Streams (como en la respuesta aceptada) para superar eso.
Ginkgo
41

Pruebe esto, puede crear un método de extensión como este:

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

y luego, simplemente llame al método de extensión:

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

Espero que esto te ayude ;-)

MCurbelo
fuente
Con mucho, el más fácil de poner en marcha
Aage,
Use en awaitlugar de .Result... o use un cliente HTTP síncrono en su lugar, si su código no puede manejar la programación asíncrona. Pero cualquier código moderno debería, de lo contrario, puede ser una señal de que su aplicación está haciendo algo mal.
Maxime Rossini
9

Si desea convertirlo a un tipo específico (por ejemplo, dentro de las pruebas) puede usar el método de extensión ReadAsAsync :

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

o siguiente para el código síncrono:

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

Actualización: también hay una opción genérica de ReadAsAsync <> que devuelve una instancia de tipo específica en lugar de una declarada por objeto:

YourType yourTypeInstance = await response.Content.ReadAsAsync<YourType>();
taras-mytofir
fuente
2
objetar yourTypeInstance = esperar respuesta.Content.ReadAsAsync (typeof (YourType)); debe ser var yourTypeInstance = waitit response.Content.ReadAsAsync <YourType> ();
Thomas.Benz
Usé Request.Content.ReadAsAsync para analizar Json y obtuve un rendimiento horrible.
W.Leto
4

Por la respuesta de rudivonstaden

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

pero si no quieres que el método sea asíncrono puedes usar

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

Wait () es importante, porque estamos haciendo operaciones asincrónicas y debemos esperar a que se complete la tarea antes de continuar.

stanimirsp
fuente
3
usando .Resultalgo diferente ?httpContent.ReadAsStringAsync().Result
mkb
.Resultbloquearía la ejecución del hilo en esa línea ... donde como txtBlock.Text.Wait()bloques en la llamada wait () ... así que estás en lo cierto, básicamente, no hay diferencia. Pero sospecho txtBlock.Text.Wait()que tomaría un parámetro entero opcional para que la GUI no se cuelgue si la ReadAsStringAsync()llamada anterior nunca regresa. Por ejemplo, lo siguiente se bloquearía por no más de 1 segundotxtBlock.Text.Wait(1000)
benhorgen
3

La respuesta rápida que sugiero es:

response.Result.Content.ReadAsStringAsync().Result

benhorgen
fuente
NO invoque Resulttareas. Corre el riesgo de bloquear su aplicación. Use async / await en su lugar.
eltiare
No diría que nunca ... a veces rápido y sucio lo hace. Pero estoy de acuerdo en que corres el riesgo de ReadAsStringAsync()no regresar, así que asegúrate de no llamarlo en tu GUI o hilo de aplicación principal.
benhorgen
1

Creo que la siguiente imagen ayuda a aquellos que necesitan venir Tcomo el tipo de retorno.

ingrese la descripción de la imagen aquí

snr
fuente
0

Puedes usar el GetStringAsyncmétodo:

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