【问题标题】:MVC Controller returning Chunked content encodingMVC 控制器返回分块内容编码
【发布时间】:2013-07-24 17:10:16
【问题描述】:

所以我有一个 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) 

【问题讨论】:

    标签: asp.net asp.net-mvc http-headers chunked-encoding


    【解决方案1】:

    我找到了解决办法。

    HTTP 1.1 标准规定,分块编码必须用长度为 0 的块来关闭,仅当请求模式为 keep-alive 时

    在 keep-alive 模式下,客户端/服务器之间的连接会针对多个请求/响应保持不变。在这种情况下,分块编码需要以长度为零的块结束,因为客户端没有其他方法可以知道前面的响应何时结束。

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

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

    HttpContext.Current.Response.Close();
    

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

    【讨论】:

      猜你喜欢
      • 2014-11-16
      • 1970-01-01
      • 2018-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-24
      相关资源
      最近更新 更多