Mendapatkan konten / pesan dari HttpResponseMessage

175

Saya mencoba untuk mendapatkan konten dari HttpResponseMessage. Seharusnya:, {"message":"Action '' does not exist!","success":false}tapi saya tidak tahu, bagaimana cara mengeluarkannya dari HttpResponseMessage.

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

Dalam hal ini txtBlock akan memiliki nilai:

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
sumber

Jawaban:

66

Anda perlu memanggil GetResponse () .

Stream receiveStream = response.GetResponseStream ();
StreamReader readStream = new StreamReader (receiveStream, Encoding.UTF8);
txtBlock.Text = readStream.ReadToEnd();
Icemanind
sumber
33
Terima kasih, tetapi mengapa saya mendapatkan kesalahan ini di sini: "System.Net.Http.HttpResponseMessage 'tidak mengandung definisi untuk' GetResponseStream 'dan tidak ada metode ekstensi' GetResponseStream 'menerima argumen pertama dari tipe' System.Net.Http.HttpResponseMessage ' dapat ditemukan "
Clem
13
@Klemzy - Karena Anda menyebutnya Asynchronisly. Coba gunakan Contentproperti sebagai gantinya. Lihat contoh di sini . Gulir ke bawah ke langkah kedua.
Icemanind
2
@ Kerzy - Lihat contoh di sini . Gulir ke bawah ke langkah kedua. Jika Anda tidak dapat mengetahuinya, saya akan mengedit jawaban saya dan memberikan contoh untuk Anda
Icemanind
17
Jawaban ini benar-benar di luar topik, OP menggunakan HttpClient, bukan HttpWebRequest/ HttpWebResponse.
Maxime Rossini
1
Pertanyaannya adalah sehubungan dengan HttpCient, respons Anda didasarkan pada HttpWebRequest yang usang dan usang.
Payam
370

Saya pikir pendekatan termudah adalah mengubah baris terakhir

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

Dengan cara ini Anda tidak perlu memperkenalkan pembaca aliran apa pun dan Anda tidak memerlukan metode ekstensi apa pun.

rudivonstaden
sumber
5
Tidak yakin mengapa ini bukan jawaban yang diterima, terutama karena ini memberi Anda kemampuan untuk dengan mudah membuat cerita bersambung konten ke objek Anda.
Jason McKindly
3
ReadAsStringAsync tidak menangani kesalahan dengan baik IMHO.
stannius
16
Anda juga dapat menggunakan Response.Content.ReadAsStringAsync (). Hasil alih-alih menggunakan menunggu
Justin
8
Berhati-hatilah: ReadAsStringAsync () dapat melempar jika Anda memiliki emotikon atau karakter Unicode lainnya dalam respons. Saya harus menggunakan Streaming (seperti dalam jawaban yang diterima) untuk mengatasinya.
Ginkgo
41

Coba ini, Anda dapat membuat metode ekstensi seperti ini:

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

dan kemudian, panggil metode ekstensi dengan mudah:

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

Saya harap ini membantu Anda ;-)

MCurbelo
sumber
Sejauh ini yang termudah untuk bangkit dan berlari
Aage
Silakan gunakan awaitsebagai ganti .Result... atau gunakan klien HTTP yang sinkron sebagai gantinya, jika kode Anda tidak dapat menangani pemrograman async. Tetapi kode modern apa pun harus, jika tidak, itu mungkin pertanda aplikasi Anda melakukan sesuatu yang salah.
Maxime Rossini
9

Jika Anda ingin melemparkannya ke jenis tertentu (misalnya dalam tes), Anda dapat menggunakan metode ekstensi ReadAsAsync :

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

atau mengikuti kode sinkron:

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

Pembaruan: ada juga opsi generik dari ReadAsAsync <> yang mengembalikan instance tipe spesifik alih-alih yang dideklarasikan objek:

YourType yourTypeInstance = await response.Content.ReadAsAsync<YourType>();
taras-mytofir
sumber
2
objek yourTypeInstance = menunggu respons.Content.ReadAsAsync (typeof (YourType)); harus var yourTypeInstance = menunggu respons.Content.ReadAsAsync <YourType> ();
Thomas.Benz
Saya menggunakan Request.Content.ReadAsAsync untuk mem-parsing Json dan mendapatkan kinerja yang mengerikan.
W.Leto
4

Dengan jawaban rudivonstaden

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

tetapi jika Anda tidak ingin membuat metode async Anda dapat menggunakan

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

Tunggu () itu penting, karena kita sedang melakukan operasi async dan kita harus menunggu tugas selesai sebelum melanjutkan.

stanimirsp
sumber
3
menggunakan .Resultberbeda ?,httpContent.ReadAsStringAsync().Result
mkb
.Resultakan memblokir eksekusi utas pada baris itu ... di mana sebagai txtBlock.Text.Wait()blok pada panggilan wait () ... jadi Anda benar bahwa pada dasarnya tidak ada perbedaan. Tapi saya menduga txtBlock.Text.Wait()akan mengambil parameter integer opsional sehingga GUI tidak hang jika ReadAsStringAsync()panggilan sebelumnya tidak pernah kembali. Misalnya, yang berikut ini akan diblokir tidak lebih dari 1 detiktxtBlock.Text.Wait(1000)
benhorgen
3

Jawaban cepat yang saya sarankan adalah:

response.Result.Content.ReadAsStringAsync().Result

benhorgen
sumber
JANGAN memanggil Resulttugas. Anda berisiko mengunci aplikasi Anda. Gunakan async / tunggu saja.
eltiare
Saya tidak akan mengatakan tidak pernah ... terkadang cepat dan kotor menyelesaikannya. Tapi saya setuju Anda menjalankan risiko ReadAsStringAsync()tidak kembali, jadi pastikan untuk tidak menyebutnya di GUI atau utas aplikasi utama Anda.
benhorgen
1

Saya pikir gambar berikut ini membantu bagi mereka yang perlu datang Tsebagai tipe pengembalian.

masukkan deskripsi gambar di sini

snr
sumber
0

Anda dapat menggunakan GetStringAsyncmetode ini:

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