.NET Core中如何使用HttpClient读取HTTP响应头值
报错原因
两个问题导致你拿到这个编译错误:
- 调用
Headers的对象不对:responseTask是Task<HttpResponseMessage>类型的异步任务实例,本身不存储HTTP响应的任何信息,自然没有Headers属性。你已经通过responseTask.Result拿到了实际的HTTP响应对象result(HttpResponseMessage类型),响应头都存在这个对象上。 - 取头值的方法名写错:
HttpHeaders类提供的多值读取方法是TryGetValues,不是字典用的TryGetValue,该方法返回布尔值表示目标头是否存在,匹配到的头值通过out参数返回,类型是IEnumerable<string>(单个HTTP头支持存多个值),不能直接在方法返回值上调用FirstOrDefault()。
另外要注意HTTP响应头分两个存储区域,找头的时候需要都覆盖到:
- 通用响应头、自定义业务头(比如你要读的
X-TotalResults)默认存在HttpResponseMessage.Headers下 - 和响应内容相关的头(比如Content-Type、Content-Length)存在
HttpResponseMessage.Content.Headers下,部分自定义头也可能被放在这个位置
修正后的代码(适配你当前的同步写法)
using (var client = new HttpClient()) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", HttpContext.Session.GetString("JwtToken")); var url = $"...some url"; var requestUri = new Uri(url); var responseTask = client.GetAsync(requestUri); responseTask.Wait(); var result = responseTask.Result; // 读取X-TotalResults头 string xTotalResults = null; // 先从响应通用头找 if (result.Headers.TryGetValues("X-TotalResults", out var headerVals)) { xTotalResults = headerVals.FirstOrDefault(); } // 通用头没找到就去内容头找 if (string.IsNullOrEmpty(xTotalResults) && result.Content.Headers.TryGetValues("X-TotalResults", out var contentHeaderVals)) { xTotalResults = contentHeaderVals.FirstOrDefault(); } if (result.IsSuccessStatusCode) { var reportResults = Task.Run(async() => await result.Content.ReadAsAsync<JArray>()).Result; // 这里就可以正常使用xTotalResults变量 return reportResults; } }
优化建议
你当前用.Wait()、.Result的同步阻塞方式调用异步方法,在ASP.NET带同步上下文的场景下很容易触发死锁,生产环境更推荐全程使用async/await的异步写法,参考如下:
public async Task<JArray> FetchReportData() { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", HttpContext.Session.GetString("JwtToken")); var requestUrl = "...some url"; // 直接await获取响应结果,不需要手动Wait、取Result var response = await client.GetAsync(requestUrl); // 读取头逻辑和上面一致 string xTotalResults = null; if (response.Headers.TryGetValues("X-TotalResults", out var headerVals)) { xTotalResults = headerVals.FirstOrDefault(); } if (string.IsNullOrEmpty(xTotalResults) && response.Content.Headers.TryGetValues("X-TotalResults", out var contentHeaderVals)) { xTotalResults = contentHeaderVals.FirstOrDefault(); } // 内置方法校验请求状态,失败直接抛出对应HTTP异常 response.EnsureSuccessStatusCode(); // 直接await读内容,不需要包一层Task.Run var reportData = await response.Content.ReadAsAsync<JArray>(); return reportData; } }
内容的提问来源于stack exchange,提问作者Vasanth R
相关产品推荐
相关产品推荐

