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
}

Jawaban:


66

Anda perlu memanggil GetResponse () .

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

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.


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 ;-)


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>();

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.


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


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


0

Anda dapat menggunakan GetStringAsyncmetode ini:

var uri = new Uri("http://yoururlhere");
var response = await client.GetStringAsync(uri);
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.