รับเนื้อหา / ข้อความจาก HttpResponseMessage


175

ฉันพยายามรับเนื้อหาของ HttpResponseMessage มันควรจะเป็น: {"message":"Action '' does not exist!","success":false}แต่ฉันไม่รู้ว่าจะนำออกจาก HttpResponseMessage ได้อย่างไร

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

ในกรณีนี้ txtBlock น่าจะมีค่า:

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
}

คำตอบ:


66

คุณจะต้องเรียกGetResponse ()

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

33
ขอบคุณ แต่ทำไมฉันถึงได้รับข้อผิดพลาดที่นี่: "System.Net.Http.HttpResponseMessage 'ไม่ได้มีคำจำกัดความสำหรับ' GetResponseStream 'และไม่มีเมธอดส่วนขยาย' GetResponseStream 'ยอมรับอาร์กิวเมนต์แรกของประเภท' System.Net.HttpResponseMessage ' สามารถพบได้ "
Clem

13
@Klemzy - เพราะคุณเรียกมันว่าอะซิงโครนัส ลองใช้Contentคุณสมบัติแทน ดูที่ตัวอย่างที่นี่ เลื่อนลงไปที่ขั้นตอนที่สอง
Icemanind

2
@Klemzy - ดูที่ตัวอย่างที่นี่ เลื่อนลงไปที่ขั้นตอนที่สอง หากคุณไม่สามารถเข้าใจได้ฉันจะแก้ไขคำตอบของฉันและยกตัวอย่างให้คุณ
Icemanind

17
คำตอบนี้มีทั้งหมดนอกเรื่อง OP จะใช้HttpClientไม่ได้/HttpWebRequest HttpWebResponse
Maxime Rossini

1
คำถามเกี่ยวกับ HttpCient การตอบกลับของคุณขึ้นอยู่กับ HttpWebRequest ที่ล้าสมัยและล้าสมัย
Payam

370

ฉันคิดว่าวิธีที่ง่ายที่สุดคือเปลี่ยนบรรทัดสุดท้ายเป็น

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

วิธีนี้คุณไม่จำเป็นต้องแนะนำโปรแกรมอ่านกระแสข้อมูลและคุณไม่ต้องการวิธีการขยายใด ๆ


5
ไม่แน่ใจว่าทำไมคำตอบนี้ไม่ได้รับการยอมรับโดยเฉพาะอย่างยิ่งเนื่องจากจะทำให้คุณสามารถทำให้เนื้อหาเป็นวัตถุได้อย่างง่ายดาย
Jason McKindly

3
ReadAsStringAsync ไม่จัดการข้อผิดพลาดได้ดี IMHO
stannius

16
คุณยังสามารถใช้ Response.Content.ReadAsStringAsync () ผลลัพธ์แทนการใช้ await
Justin

8
ระวังว่า: ReadAsStringAsync () สามารถขว้างถ้าคุณมีอีโมติคอนหรืออักขระ Unicode อื่น ๆ ในการตอบสนอง ฉันต้องใช้ Streams (เหมือนในคำตอบที่ยอมรับ) เพื่อเอาชนะมัน
แปะก๊วย

41

ลองนี้คุณสามารถสร้างวิธีการขยายแบบนี้:

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

จากนั้นเรียกวิธีการขยายอย่างง่าย ๆ :

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

ฉันหวังว่านี่จะช่วยคุณได้ ;-)


โดยไกลที่ง่ายที่สุดในการเริ่มต้นและทำงาน
Aage

กรุณาใช้awaitแทน.Result... หรือใช้ไคลเอนต์ HTTP แบบซิงโครนัสแทนหากรหัสของคุณไม่สามารถจัดการกับการเขียนโปรแกรม async แต่รหัสที่ทันสมัยใด ๆ ควรเป็นอย่างอื่นมันอาจเป็นสัญญาณว่าใบสมัครของคุณกำลังทำอะไรผิดพลาด
Maxime Rossini

9

หากคุณต้องการแปลงเป็นประเภทเฉพาะ (เช่นภายในการทดสอบ) คุณสามารถใช้วิธีการส่วนขยายReadAsAsync :

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

หรือต่อไปนี้สำหรับรหัสซิงโครนัส:

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

อัปเดต: นอกจากนี้ยังมีตัวเลือกทั่วไปของReadAsAsync <>ซึ่งจะส่งคืนอินสแตนซ์ประเภทที่เฉพาะเจาะจงแทนการประกาศด้วยวัตถุ:

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

2
วัตถุ yourTypeInstance = รอการตอบสนองContent.ReadAsAsync (typeof (YourType)); ควร var yourTypeInstance = รอการตอบสนองContent.ReadAsAsync <YourType> ();
Thomas.Benz

ฉันใช้ Request.Content.ReadAsAsync เพื่อแยกวิเคราะห์ Json และมีประสิทธิภาพที่แย่มาก
W.Leto

4

โดยคำตอบของ rudivonstaden

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

แต่ถ้าคุณไม่ต้องการทำให้วิธีการ async คุณสามารถใช้

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

เดี๋ยวก่อน () มันสำคัญเพราะเรากำลังทำการทำงานแบบ async และเราต้องรอให้งานเสร็จก่อนที่จะดำเนินการต่อไป


3
ใช้ที่.Resultแตกต่างกันไหม?httpContent.ReadAsStringAsync().Result
mkb

.Resultจะบล็อกการดำเนินการของเธรดในบรรทัดนั้น ... ซึ่งเป็นtxtBlock.Text.Wait()บล็อกบนการเรียกรอ () ... ดังนั้นคุณจึงถูกต้องที่ไม่มีความแตกต่าง แต่ฉันสงสัยว่าtxtBlock.Text.Wait()จะใช้พารามิเตอร์จำนวนเต็มเผื่อเลือกดังนั้น GUI จะไม่หยุดทำงานหากการReadAsStringAsync()โทรก่อนหน้าไม่ส่งกลับ ตัวอย่างเช่นต่อไปนี้จะบล็อกไม่เกิน 1 วินาทีtxtBlock.Text.Wait(1000)
benhorgen

3

คำตอบอย่างรวดเร็วที่ฉันแนะนำคือ:

response.Result.Content.ReadAsStringAsync().Result


อย่าเรียกResultงาน คุณเสี่ยงต่อการล็อคแอปพลิเคชันของคุณ ใช้ async / คอยแทน
eltiare

ฉันจะไม่บอกว่าไม่เคย ... บางครั้งก็รวดเร็วและสกปรก แต่ฉันยอมรับว่าคุณเสี่ยงต่อการReadAsStringAsync()ไม่กลับมาดังนั้นอย่าลืมเรียกมันบน GUI หรือเธรดแอปพลิเคชันหลักของคุณ
benhorgen

1

ฉันคิดว่าภาพต่อไปนี้จะช่วยให้ผู้ที่ต้องมาTเป็นประเภทกลับคืน

ป้อนคำอธิบายรูปภาพที่นี่


0

คุณสามารถใช้GetStringAsyncวิธีการ:

var uri = new Uri("http://yoururlhere");
var response = await client.GetStringAsync(uri);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.