所以我有一个 MVC 项目。此 MVC 项目包含一个控制器,需要将内容流式传输回客户端。当流媒体开始时,无法确定内容长度(它是即时计算的)。所以我打开 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 标头插入输出流,因为流已经被写入!
在这两种情况下,控制器都会继续返回 null(或 EmptyActionResult)。
我认为异常是由于 MVC 堆栈要求在 Controller 完成执行后每个 ActionResult 设置 HTTP 标头而引起的。如果是这种情况,如何在 MVC 中实现分块流?
提前致谢!
编辑:被抛出的确切异常是:
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)