Ottenere contenuti / messaggi da HttpResponseMessage


175

Sto cercando di ottenere contenuti di HttpResponseMessage. Dovrebbe essere:, {"message":"Action '' does not exist!","success":false}ma non lo so, come estrarlo da HttpResponseMessage.

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

In questo caso txtBlock avrebbe valore:

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
}

Risposte:


66

Devi chiamare GetResponse () .

Stream receiveStream = response.GetResponseStream ();
StreamReader readStream = new StreamReader (receiveStream, Encoding.UTF8);
txtBlock.Text = readStream.ReadToEnd();

33
Grazie, ma perché ottengo questo errore qui: "System.Net.Http.HttpResponseMessage" non contiene una definizione per "GetResponseStream" e nessun metodo di estensione "GetResponseStream" che accetta un primo argomento di tipo "System.Net.Http.HttpResponseMessage" potrebbe essere trovato "
Clem,

13
@Klemzy - Perché lo chiami in modo asincrono. Prova Contentinvece a usare la proprietà. Guarda l' esempio qui . Scorri verso il basso fino al secondo passaggio.
Icemanind

2
@Klemzy - Guarda l' esempio qui . Scorri verso il basso fino al secondo passaggio. Se non riesci a capirlo, modificherò la mia risposta e ti darò un esempio per te
Icemanind

17
Questa risposta è totalmente fuori tema, l'OP sta usando HttpClient, non HttpWebRequest/ HttpWebResponse.
Maxime Rossini,

1
La domanda riguarda HttpCient, la tua risposta si basa su HttpWebRequest obsoleto e obsoleto.
Payam,

370

Penso che l'approccio più semplice sia quello di cambiare l'ultima riga in

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

In questo modo non è necessario introdurre alcun lettore di stream e non sono necessari metodi di estensione.


5
Non sono sicuro del perché questa non sia la risposta accettata, soprattutto perché ti dà la possibilità di serializzare facilmente i contenuti nei tuoi oggetti.
Jason McKindly,

3
ReadAsStringAsync non gestisce bene gli errori IMHO.
stannius,

16
Puoi anche usare Response.Content.ReadAsStringAsync (). Risultato invece di usare waitit
Giustino

8
Attenzione però: ReadAsStringAsync () può essere lanciato se nella risposta sono presenti emoticon o altri caratteri Unicode. Ho dovuto usare gli stream (come nella risposta accettata) per superare questo.
Ginkgo,

41

Prova questo, puoi creare un metodo di estensione come questo:

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

e quindi, basta chiamare il metodo di estensione:

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

Spero che questo ti sia d'aiuto ;-)


Di gran lunga il più facile da mettere in piedi
Aage,

Utilizzare awaitinvece di .Result... oppure utilizzare un client HTTP sincrono, se il codice non è in grado di gestire la programmazione asincrona. Ma qualsiasi codice moderno dovrebbe, altrimenti potrebbe essere un segno che l'applicazione sta facendo qualcosa di sbagliato.
Maxime Rossini,

9

Se si desidera eseguirne il cast su un tipo specifico (ad esempio all'interno dei test) è possibile utilizzare il metodo di estensione ReadAsAsync :

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

o seguenti per il codice sincrono:

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

Aggiornamento: esiste anche un'opzione generica di ReadAsAsync <> che restituisce un'istanza di tipo specifico anziché quella dichiarata dall'oggetto:

YourType yourTypeInstance = await response.Content.ReadAsAsync<YourType>();

2
oggetto yourTypeInstance = await response.Content.ReadAsAsync (typeof (YourType)); dovrebbe essere var yourTypeInstance = await response.Content.ReadAsAsync <YourType> ();
Thomas.Benz,

Ho usato Request.Content.ReadAsAsync per analizzare Json e ho ottenuto prestazioni orribili.
W.Leto,

4

Dalla risposta di rudivonstaden

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

ma se non vuoi rendere il metodo asincrono puoi usare

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

Wait () è importante, perché stiamo eseguendo operazioni asincrone e dobbiamo attendere il completamento dell'attività prima di andare avanti.


3
usando .Resultqualcosa di diverso ?,httpContent.ReadAsStringAsync().Result
mkb

.Resultbloccherebbe l'esecuzione del thread su quella linea ... dove come txtBlock.Text.Wait()blocchi nella chiamata wait () ... quindi hai ragione che sostanzialmente non c'è differenza. Ma sospetto txtBlock.Text.Wait()che prenderebbe un parametro intero opzionale in modo che la GUI non si blocchi se la ReadAsStringAsync()chiamata precedente non ritorna mai. Ad esempio, ciò che segue si bloccherebbe per non più di 1 secondotxtBlock.Text.Wait(1000)
benhorgen

3

La risposta rapida che suggerisco è:

response.Result.Content.ReadAsStringAsync().Result


NON chiamare le Resultattività. Rischi di bloccare l'applicazione. Utilizzare invece async / waitit.
eltiare

Non direi mai ... a volte lo fa veloce e sporco. Ma sono d'accordo che corri il rischio di ReadAsStringAsync()non tornare, quindi assicurati di non chiamarlo sulla tua GUI o sul thread dell'applicazione principale.
Benhorgen,

1

Penso che la seguente immagine sia di aiuto per coloro che devono trovarsi Tcome tipo di ritorno.

inserisci qui la descrizione dell'immagine


0

Puoi usare il GetStringAsyncmetodo:

var uri = new Uri("http://yoururlhere");
var response = await client.GetStringAsync(uri);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.