MVC控制器返回分块内容编码

所以我有一个MVC项目。 这个MVC项目包含一个Controller,需要将内容传输回客户端。 流式传输开始时,无法确定内容长度(它是在即时计算的)。 所以我打开HttpContext.Current.Response.OutputStream,并定期开始写入和刷新(我已经禁用了缓冲输出,并附加了相应的http头文件):

while (some condition){

   HttpContext.Current.Response.OutputStream.Write(buffer, 0, buffer.Length);
   HttpContext.Current.Response.Flush();
}

如果我然后强制关闭流:

HttpContext.Current.Response.Close();

它没有正确结束分块内容(它不会在末尾附加0长度的块,以向客户端指示EOF)。

如果我更优雅地关闭输出流:

HttpContext.Current.Response.End();

要么

HttpContext.Current.ApplicationInstance.CompleteRequest();

它正确地关闭流(零长度块附加到结束),但我得到应用程序抛出的异常,表明它不能将HTTP头插入输出流,因为该流已经写入!

在这两种情况下,Controller继续返回null(或EmptyActionResult)。

我假设异常是由于MVC堆栈要求每个ActionResult在Controller完成执行后设置HTTP标头而引起的。 如果是这种情况,那么在MVC中如何实现一个Chunked流?

提前致谢!

编辑 :被抛出的确切异常是:

Uncaught Exception: System.Web.HttpException (0x80004005): Server cannot set status after HTTP headers have been sent.
   at System.Web.Http.WebHost.HttpControllerHandler.EndProcessRequest(IAsyncResult result)
   at System.Web.Http.WebHost.HttpControllerHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

我找到了解决方案。

HTTP 1.1标准规定,只有在请求模式保持活动状态时,分块编码必须用0长度的块关闭

在保持活动模式下,客户端/服务器之间的连接会持续多个请求/响应。 分块编码需要在此上下文中以零长度块结束,因为没有其他方式让客户端知道前一个响应何时结束。

如果指定“Connection:close”作为头部,而不是“Connection:keep-alive”,则连接不会在请求之间持久,客户端可以使用连接关闭作为响应终止的指示,并且不需要指示EOF的0长度块。

我刚刚决定使用以下方式手动关闭HttpResponse:

HttpContext.Current.Response.Close();

虽然先前在代码中指定告诉客户端连接将在EOF上关闭。 这解决了客户端没有收到0长度块的问题,因为现在客户端不需要它。

链接地址: http://www.djcxy.com/p/14909.html

上一篇: MVC Controller returning Chunked content encoding

下一篇: WPF: Multiple screens