从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
}

Answers:


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.Http.HttpResponseMessage”的第一个参数可以找到“
Clem

13
@Klemzy-因为您异步地调用它。尝试使用Content属性代替。看这里例子。向下滚动到第二步。
Icemanind

2
@Klemzy-在这里查看示例。向下滚动到第二步。如果您
无法解决

17
这个答案完全是题外话,OP正在使用HttpClient,而不是HttpWebRequest/ HttpWebResponse
Maxime Rossini'Mar

1
问题是关于HttpCient的,您的响应基于过时和过时的HttpWebRequest。
Payam

370

我认为最简单的方法是将最后一行更改为

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

这样,您不需要引入任何流阅读器,也不需要任何扩展方法。


5
不确定为什么这不是可接受的答案,特别是因为这使您能够轻松地将内容序列化到对象中。
杰森·麦金德利

3
ReadAsStringAsync无法很好地处理错误,恕我直言。
stannius '16

16
您还可以使用Response.Content.ReadAsStringAsync()。Result代替使用await-
贾斯汀

8
但是要当心:如果响应中包含表情符号或其他一些Unicode字符,则可能抛出ReadAsStringAsync()。我不得不使用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客户端。但是任何现代代码都应该如此,否则可能表明您的应用程序做错了什么。
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
object 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();`

但是,如果您不想使方法异步,则可以使用

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

Wait()很重要,因为我们正在执行异步操作,因此我们必须等待任务完成才能继续。


3
使用.Result任何其他方法吗?,httpContent.ReadAsStringAsync().Result
mkb

.Result会阻塞该行的执行...在txtBlock.Text.Wait()wait()调用处被阻塞...所以您是正确的,基本上没有区别。但是我怀疑txtBlock.Text.Wait()会采用一个可选的整数参数,以便如果先前的ReadAsStringAsync()调用永不返回,则GUI不会挂起。例如,以下内容将阻止不超过1秒的时间txtBlock.Text.Wait(1000)
benhorgen

3

我建议的快速答案是:

response.Result.Content.ReadAsStringAsync().Result


不要调用Result任务。您有锁定您的应用程序的风险。请改用async / await。
Eltiare

我不会说永远不会...有时候又快又脏又能完成它。但是我同意您确实有ReadAsStringAsync()返回失败的风险,因此请确保不要在GUI或主应用程序线程上调用它。
benhorgen

1

我认为以下图像对那些需要T作为返回类型的人有所帮助。

在此处输入图片说明


0

您可以使用以下GetStringAsync方法:

var uri = new Uri("http://yoururlhere");
var response = await client.GetStringAsync(uri);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.