我最近开始为客户开发一个多文件上传 HTTP 页面。
他想要一切都在 HTTP、Javascript 和 HTML 中,需要能够传输大文件(每个文件最多 800 兆字节),并且他还想要一个用于上传的进度条。Flash 或 Silverlight 不是一个被接受的选项,最后,第三方组件也不被接受,因为在没有太多麻烦的情况下需要深入的可定制性。
现在,我明白了整个概念。您有一个主页,其中有一个iframe
(ewww,我说的是 i-word - 我知道)。这iframe
指向form
其中有文件上传。这样,一旦form
提交,访问者所在的原始页面不会重新加载,让原始页面运行一些AJAX,不断询问传输进度。
第一次尝试
我首先通过将文件直接声明为操作方法的参数来开始在 MVC 中获取文件,如下所示。
public ActionResult UploadFile(HttpPostedFile upload) {
...
}
但是,尽管 MVC 给我的帮助很大,但变量上的InputStream
属性或SaveAs(...)
方法都没有帮助我。upload
BeginExecute 和 GetBufferedInputStream
很快我找到了 .NET 4.0 中引入的一种方法,称为HttpRequest.GetBufferedInputStream()
. 这种方法特别允许我接收文件流并以增量和异步的方式读取它。
当触发特定 URL 时,我重写了BeginExecute
控制器的方法,并将读取功能放在那里,就像这样。
protected override IAsyncResult BeginExecute(System.Web.Routing.RequestContext requestContext, AsyncCallback callback, object state)
{
if (requestContext.HttpContext.Request.Url.AbsolutePath.StartsWith("/Home/UploadFile"))
{
//we're doing a file upload
var streamSource = requestContext.HttpContext.Request.GetBufferedInputStream();
//read from stream, write to file
}
}
这一切都很好......当AJAX不进入并中断时。你看,如果我的 AJAX 脚本正在运行(在iframe
上传开始后 10 秒执行),那么(当它发出GET
请求时)该请求会中断正在读取文件的流,即使它是在不同的操作上,甚至当它在不同的控制器上时。
我收到的错误如下:
客户端已断开连接,因为基础请求已完成。不再有 HttpContext 可用。
我能做些什么呢?