C# 读取 HttpResponseMessage

4

我第一次使用.net的Httpclient,发现很难。我已经成功调用服务器并从中接收到响应,但卡在了读取响应的阶段。以下是我的代码:

if (Method == HttpVerb.POST)
     response = client.PostAsync(domain, new StringContent(parameters)).Result;
else
     response = client.GetAsync(domain).Result;

if (response != null)
{
     var responseValue = string.Empty;

     Task task = response.Content.ReadAsStreamAsync().ContinueWith(t =>
     {
         var stream = t.Result;
         using (var reader = new StreamReader(stream))
         {
             responseValue = reader.ReadToEnd();
         }
     });


     return responseValue;
}

虽然服务正在返回数据,但responseValue中仍然包含{}。我该如何解决这个问题?

该项目使用的是 .Net 4。


你正在使用WCF服务还是Web服务?响应的状态是什么?responseValue.StatusCode = ? - PrinceT
你在返回之前不应该等待任务吗? - DavidG
@PrinceT 我正在调用 REST 服务。 - Haris
@DavidG 我应该在哪里使用await?无论我在哪里放置await,VS都会显示错误,提示“await运算符只能在异步方法中使用”。 - Haris
@Haris,由于您的函数不是异步的,请使用Task.Wait(),请查看我的答案。 - DavidG
2个回答

11
您正在创建一个异步任务,但在返回之前没有等待它完成。这意味着您的responseValue从未被设置。
要解决此问题,请在返回之前执行以下操作:
task.Wait();

所以你的函数现在看起来像这样:
if (Method == HttpVerb.POST)
     response = client.PostAsync(domain, new StringContent(parameters)).Result;
else
     response = client.GetAsync(domain).Result;

if (response != null)
{
     var responseValue = string.Empty;

     Task task = response.Content.ReadAsStreamAsync().ContinueWith(t =>
     {
         var stream = t.Result;
         using (var reader = new StreamReader(stream))
         {
             responseValue = reader.ReadToEnd();
         }
     });

     task.Wait();

     return responseValue;
}

如果您更喜欢使用await(这可能是更好的选择),那么您需要将包含此代码的函数设为async,像这样:

public string GetStuffFromSomewhere()
{
    //Code above goes here

    task.Wait();
}

Becomes:

public async string GetStuffFromSomewhere()
{
    //Code above goes here

    await ...
}

ContinueWith 中的函数是否正在执行? - DavidG
是的,它正在执行。注意到 t.Result.Length 中有 2。 - Haris
我建议阅读这篇文章,了解如何使用HttpClient:http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client - DavidG
好的,我通过更改域和参数获取了数据。域已从 http://mydomain.com:38080/workshop/ 更改为 http://mydomain.com:38080/workshop/rest/login,参数已从 rest/login?username=usr&password=pwd 更改为 username=usr&password=pwd。为什么会这样呢?这将导致获取 cookie 出现问题,因为它们是在域级别设置的。 - Haris
啊,我现在明白了。尽管这不是你的解决方案,但我的回答仍然适用。 - DavidG
显示剩余2条评论

0

试试这个

                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(obj.Url);
                    HttpWebResponse response = null;

                    try
                    {
                        response = request.GetResponse() as HttpWebResponse;
                    }
                    catch (Exception ex)
                    {
                    }

1
当新的 HttpClient 可用时,不应使用 WebRequest。此外,这并没有回答所提出的问题。 - DavidG
我之前使用了 WebRequest,但无法读取 cookies,所以转移到了 HttpClient。除此之外,WebRequest 运行得非常完美。 - Haris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接