asp.net – PushStreamContent没有发送最终的零长度块来表示流的
我需要使用Odata协议通过WebAPI批量导出内容.我们正在尝试使用PushStreamContent直接将结果流出数据库.当我在本地IIS实例中运行该服务时,它工作得很好,但当我将其推送到服务器时,它将流式传输数据并暂停并在最后2千字节“挂起”.
我通过跟踪文件大小来验证.在本地运行中,我将获得一个9094KB的文件,当我将相同的代码部署到服务器时,我获得9092KB,然后连接保持打开并且传输停止.如果我杀死客户端并查看该文件,我将看到流中的json在写入中间被切断.此外,我可以查看IIS中的打开连接,并看到该连接仍处于活动状态. 无论如何,为什么PushStreamContent似乎只是停止发送数据而不关闭流?如果发生错误,则流和连接将关闭. public HttpResponseMessage GetBulkExport(ODataQueryOptions<vwBulkExport> options) { var reportData = options.ApplyTo(dbContext.vwBulkExport,new ODataQuerySettings() { EnsureStableOrdering = false }); return new ResponseStreamer(Request).StreamAsync(reportData); } public class ResponseStreamer { private HttpRequestMessage request; public ResponseStreamer(HttpRequestMessage request) { this.request = request; } public HttpResponseMessage StreamAsync(IQueryable data) { HttpResponseMessage response = request.CreateResponse(); response.Content = new PushStreamContent( async (outputStream,httpContent,transportContext) => { try { int counter = 0; foreach (var item in data) { counter++; string json = JsonConvert.SerializeObject(item); var buffer = Encoding.UTF8.GetBytes(json); await outputStream.WriteAsync(buffer,buffer.Length); if (counter == 10) { counter = 0; await outputStream.FlushAsync(); } } } finally { await outputStream.FlushAsync(); outputStream.Close(); outputStream.Dispose(); } }); return response; } } 这是我的客户端代码 using (var writer = File.OpenWrite("C:temp" + Guid.NewGuid().ToString())) { var client = new RestClient("http://localhost"); var url = "/odata/BulkExport"; var request = new RestRequest(url); request.AddHeader("authorization",string.Format("Bearer {0}",authToken)); request.ResponseWriter = (responseStream) => responseStream.CopyTo(writer); var response = client.DownloadData(request); } 更新 我已经做了大量的测试,而我认为正在发生的是流永远不会被关闭(因此最后一个块永远不会被发送)我通过将上面的数据迭代更改为此来得出这个结论: for (int count = 0; count < 1000; count++) //foreach (var item in data) { string json = JsonConvert.SerializeObject(count.ToString()) + Environment.NewLine; var buffer = Encoding.Default.GetBytes(json); await outputStream.WriteAsync(buffer,buffer.Length); } 我所看到的是它只返回600“行”.似乎还缺少2 KB.然后我将循环更改为计数< 601并且传输整个流,但是流永远不会关闭.我认为正在发生的是内部缓冲区大小,如果大约4K(这是0-600打印出来的数字),并且由于流没有关闭,最后几个字节永远不会被接收.这有意义吗? 无论如何,为什么流不关闭?我终于得到了它,我没有看到任何错误抛出. 更新 我发现了更多信息. HTTP 1.1规范说,分块流需要以零长度块结束.经过一番挖掘,我发现它应该发生,但无论出于何种原因,它都不会发生.在我的客户端,我删除了Connection:Keep-Alive标头并将其替换为Connection:Close我遇到了同样的问题,但是一旦我强制连接关闭(通过关闭我的测试应用程序),最后几个字节写入磁盘一切都很好.这就是我所知道的零长度块没有被发送的方式. 所以现在问题已成为现实.为什么关闭流时没有发送最终的零长度块?从我读过的,调用HttpContext.Current.ApplicationInstance.CompleteRequest();应强制请求结束并写出该块.我添加了作为finally块中的最后一行,并使用调试器,我知道它正在运行.但是,该块仍未设置. 请记住,所有这些都适用于我在IIS中托管的开发机器,但不适用于Web服务器. 我的机器运行的是Windows 10,我安装了asp.net 5,而IIS7的所有默认值都是. Web服务器是Windows Server(我不确定版本)运行IIS8但它只安装了asp.net 4.5.我最初的预感是这是问题 – 不同版本的asp.net框架,但我检查了,该项目只针对ASP.NET 4.5.我仍然会尝试更新服务器,但由于我的目标是4.5,我认为它不会有任何好处. 解决方法
我认为问题是由.net框架中的错误引起的.将服务器更新到.net 4.6后,它正在运行.
这是我应用的补丁. https://www.microsoft.com/en-us/download/details.aspx?id=48137 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 如何在gridview中将navigateurl添加到超链接
- ASP.NET MVC的提示和ASP.NET WebForms开发人员的课程
- asp.net – 对于想要将一切都变成.NET控件的人,您会怎么说?
- ASP.NET Active Directory成员资格提供程序和SQL配置文件提
- asp.net – 元素’system.webServer’有无效的子元素’重写
- 可以使用ASP.NET路由为.ashx(IHttpHander)处理程序创建“干
- .net – 如何使用SmtpClient.SendAsync发送带有附件的电子邮
- asp.net – 会话固定 – 表单身份验证
- ASP.NET Core 2.0 Identity中的Cookies.ApplicationCookie.
- 使用IronRuby的ASP.net MVC?
- asp.net-mvc – 使用Moq查找DbSet(EntityFramewo
- asp.net – 如何获取当前的月份和年份
- asp.net-mvc – AntiXss保护Html模型属性
- asp.net-mvc-2 – 在Visual Studio 2010 RC中更改
- asp.net – 无法加载文件或程序集“Microsoft.Te
- asp.net核心 – 在ASP.NET核心应用程序中使用NLo
- asp.net-mvc – 如何将特定于HTTP-Request的对象
- asp.net-mvc – MVC – 如何从get请求获取参数值
- asp.net-core – 使用IdentityServer4生成访问令
- asp.net – 带有服务器端资源字符串的Html输入标