C# HttpClient 在将内容复制到流时随机出错

标签 c# asp.net json iis httpclient

我使用以下代码对在 IIS 服务器上运行的远程 ASP .Net WebApi 执行 HTTP GET 请求。该请求返回一个大小约为 5 兆字节的 JSON 对象。几乎所有的时间,这个请求都会成功并且我得到正确的 JSON 响应,但是有些东西(大约 2-3% 的时间,随机分布)我在响应正文中得到一个不完整的 JSON。响应代码为 200 OK,但 JSON 数据在随机位置被截断。 在 Fiddler 中,我确实看到响应 JSON 在随机位置被剪切,所以服务器似乎出于某种原因在中间关闭了连接。

我在其他 SO 线程中读到,移动到 HTTP V1.0 或将连接 header 设置为“关闭”可能会解决问题,但它对我不起作用。它是我在这里缺少的 IIS 服务器设置吗?还是错误的客户端配置?

当从同一 api 返回更小的 JSON 响应(小于 1 兆字节)的其他路由上使用相同代码时,问题似乎不会重现。

同样重要的是要注意我们的客户端和 IIS 服务器 (Incapsula) 之间有一些负载平衡器机制。此负载均衡器还提供 DDos 预防。

这是我的 C# 代码(我使用的是最新的 HttpClient 版本):

 using (var httpClient = new HttpClient())
 {
     var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri("https://api-real.bgtm.com/Orders"));

     using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage))
     {
          InstResponse s = httpResponseMessage.Content.ReadAsAsync<InstResponse>().GetAwaiter().GetResult();
         Console.Write("Finished without error.");
     }
 }

这是我在尝试从响应流中读取不完整的 JSON 时得到的完整异常详细信息:

{System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: The server returned an invalid or unrecognized response.
   at System.Net.Http.HttpConnection.FillAsync()
   at System.Net.Http.HttpConnection.CopyToExactLengthAsync(Stream destination, UInt64 length, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnection.ContentLengthReadStream.CompleteCopyToAsync(Task copyTask, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnection.HttpConnectionResponseContent.SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken)
   at System.Net.Http.HttpContent.LoadIntoBufferAsyncCore(Task serializeToStreamTask, MemoryStream tempBuffer)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpContent.LoadIntoBufferAsyncCore(Task serializeToStreamTask, MemoryStream tempBuffer)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at ConsoleApp1.Program.MainAsync ()}

我还可以添加来自 WireShark 的屏幕截图,显示服务器是第一个发送 FIN 消息的。服务器 IP 为 107.154.192.59,客户端 IP 为 10.10.80.146:ScreenShot
很绝望,有人见过这种不一致的行为吗? 谢谢

最佳答案

.GetAwaiter().GetResult() 不是异步操作。错误是偶发的原因。

将您的代码修改为:

InstResponse s = await httpResponseMessage.Content.ReadAsAsync<InstResponse>();

关于C# HttpClient 在将内容复制到流时随机出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59460265/

相关文章:

c# - 如何使用字典的复合键?

c# - 如何摆脱流畅的 ValidationResult 的 PropertyName 中的点

javascript - 如何在 Javascript 中禁用 RadioButtonList 中的某个单选按钮

c# - 使用带有 HTTPS 证书的 System.Net.WebClient

c# - Intranet 站点的 ASP.NET Identity + Windows 身份验证

json - UITableview在numberOfRowsInSection崩溃; NSDictionary中的Json到UITableview

ios - RestKit JSON 空值崩溃

asp.net-mvc - ASP.NET MVC - 将 Json 结果与 ViewResult 结合起来

asp.net - 如何在 vb.net 中做正则表达式

c# - 在 IIS 服务器之间传递 Windows 身份验证