Obtenir le contenu / message de HttpResponseMessage

175

J'essaye d'obtenir le contenu de HttpResponseMessage. Cela devrait être {"message":"Action '' does not exist!","success":false}:, mais je ne sais pas, comment le sortir de HttpResponseMessage.

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

Dans ce cas, txtBlock aurait la valeur:

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
la source

Réponses:

66

Vous devez appeler GetResponse () .

Stream receiveStream = response.GetResponseStream ();
StreamReader readStream = new StreamReader (receiveStream, Encoding.UTF8);
txtBlock.Text = readStream.ReadToEnd();
Icemanind
la source
33
Merci, mais pourquoi j'obtiens cette erreur ici: "System.Net.Http.HttpResponseMessage 'ne contient pas de définition pour' GetResponseStream 'et aucune méthode d'extension' GetResponseStream 'acceptant un premier argument de type' System.Net.Http.HttpResponseMessage ' pourrait être trouvé "
Clem
13
@Klemzy - Parce que vous l'appelez de manière asynchrone. Essayez Contentplutôt d' utiliser la propriété. Regardez l' exemple ici . Faites défiler jusqu'à la deuxième étape.
Icemanind
2
@Klemzy - Regardez l' exemple ici . Faites défiler jusqu'à la deuxième étape. Si vous ne pouvez pas le comprendre, je modifierai ma réponse et vous donnerai un exemple pour vous
Icemanind
17
Cette réponse est totalement hors sujet, l'OP utilise HttpClient, pas HttpWebRequest/ HttpWebResponse.
Maxime Rossini
1
La question concerne HttpCient, votre réponse est basée sur HttpWebRequest obsolète et obsolète.
Payam
371

Je pense que l'approche la plus simple consiste simplement à changer la dernière ligne en

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

De cette façon, vous n'avez pas besoin d'introduire de lecteurs de flux et vous n'avez besoin d'aucune méthode d'extension.

Rudivonstaden
la source
5
Je ne sais pas pourquoi ce n'est pas la réponse acceptée, d'autant plus que cela vous donne la possibilité de sérialiser facilement le contenu dans vos objets.
Jason McKindly
3
ReadAsStringAsync ne gère pas bien les erreurs à mon humble avis.
stannius
16
Vous pouvez également utiliser Response.Content.ReadAsStringAsync (). Result au lieu d'utiliser await
Justin
8
Attention cependant: ReadAsStringAsync () peut lancer si vous avez des émoticônes ou d'autres caractères Unicode dans la réponse. J'ai dû utiliser Streams (comme dans la réponse acceptée) pour surmonter cela.
Ginkgo
41

Essayez ceci, vous pouvez créer une méthode d'extension comme celle-ci:

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

puis, appelez simplement la méthode d'extension:

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

J'espère que cela vous aidera ;-)

MCurbelo
la source
De loin le plus facile à démarrer
Aage
Veuillez utiliser à la awaitplace de .Result... ou utiliser un client HTTP synchrone à la place, si votre code ne peut pas gérer la programmation asynchrone. Mais tout code moderne devrait, sinon cela peut être un signe que votre application fait quelque chose de mal.
Maxime Rossini
9

Si vous souhaitez le convertir en un type spécifique (par exemple dans les tests), vous pouvez utiliser la méthode d'extension ReadAsAsync :

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

ou suivant pour le code synchrone:

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

Mise à jour: il existe également une option générique de ReadAsAsync <> qui retourne une instance de type spécifique au lieu d'une instance déclarée par objet:

YourType yourTypeInstance = await response.Content.ReadAsAsync<YourType>();
taras-mytofir
la source
2
object yourTypeInstance = wait response.Content.ReadAsAsync (typeof (YourType)); devrait être var yourTypeInstance = await response.Content.ReadAsAsync <YourType> ();
Thomas.Benz
J'ai utilisé Request.Content.ReadAsAsync pour analyser Json et j'ai obtenu des performances horribles.
W.Leto
4

Par la réponse de rudivonstaden

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

mais si vous ne voulez pas rendre la méthode asynchrone, vous pouvez utiliser

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

Wait () c'est important, car nous faisons des opérations asynchrones et nous devons attendre que la tâche se termine avant de continuer.

stanimirsp
la source
3
en utilisant .Resultun autre ?,httpContent.ReadAsStringAsync().Result
mkb
.Resultbloquerait l'exécution du thread sur cette ligne ... alors que des txtBlock.Text.Wait()blocs lors de l'appel wait () ... vous avez donc raison de dire qu'il n'y a fondamentalement aucune différence. Mais je soupçonne txtBlock.Text.Wait()que prendrait un paramètre entier facultatif pour que l'interface graphique ne se bloque pas si l' ReadAsStringAsync()appel précédent ne revient jamais. Par exemple, ce qui suit ne bloquera pas plus d'une secondetxtBlock.Text.Wait(1000)
benhorgen
3

La réponse rapide que je suggère est:

response.Result.Content.ReadAsStringAsync().Result

Benhorgen
la source
N'appelez PAS Resultà des tâches. Vous risquez de bloquer votre application. Utilisez plutôt async / await.
eltiare le
Je ne dirais pas jamais ... parfois rapide et sale y parvient. Mais je suis d'accord que vous courez le risque de ReadAsStringAsync()ne pas revenir, alors assurez-vous de ne pas l'appeler sur votre interface graphique ou le thread principal de l'application.
benhorgen
1

Je pense que l'image suivante aide pour ceux qui doivent venir Tcomme type de retour.

entrez la description de l'image ici

snr
la source
0

Vous pouvez utiliser la GetStringAsyncméthode:

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