如何从 httpclient 调用中获取内容正文?

Posted

技术标签:

【中文标题】如何从 httpclient 调用中获取内容正文?【英文标题】:How to get content body from a httpclient call? 【发布时间】:2014-10-27 22:06:12 【问题描述】:

我一直试图弄清楚如何读取 httpclient 调用的内容,但我似乎无法理解。我得到的响应状态是 200,但我不知道如何获得返回的实际 Json,这就是我所需要的!

以下是我的代码:

async Task<string> GetResponseString(string text)

    var httpClient = new HttpClient();

    var parameters = new Dictionary<string, string>();
    parameters["text"] = text;
    Task<HttpResponseMessage> response = 
        httpClient.PostAsync(BaseUri, new FormUrlEncodedContent(parameters));

    return await response.Result.Content.ReadAsStringAsync();

我只是从一个方法中调用它:

Task<string> result =  GetResponseString(text);

这就是我得到的

response Id = 89, Status = RanToCompletion, Method = "null", Result = "StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:\r\n\r\n Connection: keep-alive\r\n Date: Mon, 27 Oct 2014 21:56:43 GMT\r\n ETag: \"5a266b16b9dccea99d3e76bf8c1253e0\"\r\n Server: nginx/0.7.65\r\n Content-Length: 125\r\n Content-Type: application/json\r\n" System.Threading.Tasks.Task&lt;System.Net.Http.HttpResponseMessage&gt;

更新:这是我当前的代码,根据 Nathan 的回复如下

    async Task<string> GetResponseString(string text)
    
        var httpClient = new HttpClient();

        var parameters = new Dictionary<string, string>();
        parameters["text"] = text;

        var response = await httpClient.PostAsync(BaseUri, new FormUrlEncodedContent(parameters));
        var contents = await response.Content.ReadAsStringAsync();

        return contents;
    

我从这个方法中调用它......

 string AnalyzeSingle(string text)
    
        try
        
            Task<string> result = GetResponseString(text);
            var model = JsonConvert.DeserializeObject<SentimentJsonModel>(result.Result);

            if (Convert.ToInt16(model.pos) == 1)
            
                _numRetries = 0;
                return "positive";
            

            if (Convert.ToInt16(model.neg) == 1)
            
                _numRetries = 0;
                return "negative";
            

            if (Convert.ToInt16(model.mid) == 1)
            
                _numRetries = 0;
                return "neutral";
            

            return "";
        
        catch (Exception e)
        
            if (_numRetries > 3)
            
                LogThis(string.Format("Exception caught [0] .... skipping", e.Message));
                _numRetries = 0;
                return "";
            
            _numRetries++;
            return AnalyzeSingle(text);
        
    

而且它会一直运行下去,它命中了线 var model = JsonConvert.DeserializeObject&lt;SentimentJsonModel&gt;(result.Result); 一次,它会继续运行,不会在另一个断点处停止。

当我暂停执行时,它说

Id = 无法评估表达式,因为当前方法的代码已优化。状态 = 无法评估表达式,因为当前方法的代码已优化。方法 = 无法评估表达式,因为当前方法的代码已优化。 , Result = 无法计算表达式,因为当前方法的代码已经过优化。

.. 我继续执行,但它只是永远运行。不知道是什么问题

【问题讨论】:

_numRetries 在哪里以及如何定义? 它在类的范围内,在构造函数中初始化为0。 AnalyzeSingle() 是我唯一使用它的地方。 您是否在调试模式下运行?优化的问题可能是因为您在发布模式下运行。 我目前在 Debug/iisExpress 【参考方案1】:

您使用 await/async 的方式充其量是很糟糕的,而且很难遵循。您将awaitTask'1.Result 混合在一起,这令人困惑。但是,看起来您正在查看最终任务结果,而不是内容。

我已经重写了你的函数和函数调用,应该可以解决你的问题:

async Task<string> GetResponseString(string text)

    var httpClient = new HttpClient();

    var parameters = new Dictionary<string, string>();
    parameters["text"] = text;

    var response = await httpClient.PostAsync(BaseUri, new FormUrlEncodedContent(parameters));
    var contents = await response.Content.ReadAsStringAsync();

    return contents;

最后的函数调用:

Task<string> result = GetResponseString(text);
var finalResult = result.Result;

甚至更好:

var finalResult = await GetResponseString(text);

【讨论】:

谢谢!!在过去的几个小时(MSDN + ***),我一直在尝试了解 async/await 的工作原理,但我显然还没有完全掌握它。你有什么建议的资源吗? 继续玩它,你最终会掌握它的窍门。一下子就掌握了一个很大的概念。 我仍然有问题。我在原始帖子上更新了我的问题。问题可能是我正在为同步执行编码,但我不确定如何解决这个问题 HttpClient实现了IDisposable,所以最好用using语句包裹起来。 @Payam 虽然它确实实现了IDisposable,但您不应该将它包装在using 语句中。这是该规则的罕见例外。有关更多信息,请参阅此帖子:aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong【参考方案2】:

如果你不想使用async,你可以添加.Result来强制代码同步执行:

private string GetResponseString(string text)

    var httpClient = new HttpClient();

    var parameters = new Dictionary<string, string>();
    parameters["text"] = text;

    var response = httpClient.PostAsync(BaseUri, new FormUrlEncodedContent(parameters)).Result;
    var contents = response.Content.ReadAsStringAsync().Result;

    return contents;
   

【讨论】:

@nbushnell 将 .Result 添加到您的 PostAsync 使其非异步 @Mike 这不是 nbushnell 所说的吗? :-) response 的类型是什么?我有类似的代码,但我需要将response 设为全局,所以我需要类型。谢谢。 @AzureSpot:响应类型为 HttpResponseMessage。

以上是关于如何从 httpclient 调用中获取内容正文?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 HttpClient 在 GET 请求正文中发送内容?

Symfony HttpClient Stream 和 chunk->getContent() 超出正文大小限制

如何从 Httpclient.SendAsync 调用中获取和打印响应

如何从 Apache HttpClient5 的 HttpResponse 中获取响应体?

MS Access |如何从邮件正文到表格获取内容?

使用 HttpClient 写入正文请求