将大file upload到ASP.NET MVC

对于我正在处理的应用程序,我需要允许用户通过我们的网站上传非常大的文件 – 也就是可能有几千兆字节。 不幸的是,ASP.NET MVC似乎在开始服务之前将整个请求加载到RAM中 – 对于这样的应用程序来说,这并不完美。 值得注意的是,试图通过如下代码绕过这个问题:

if (request.Method == "POST") { request.ContentLength = clientRequest.InputStream.Length; var rgbBody = new byte[32768]; using (var requestStream = request.GetRequestStream()) { int cbRead; while ((cbRead = clientRequest.InputStream.Read(rgbBody, 0, rgbBody.Length)) > 0) { fileStream.Write(rgbBody, 0, cbRead); } } } 

没有规避缓冲区请求到RAM的心态。 有没有简单的方法来解决这个问题?

事实certificate,我最初的代码基本上是正确的; 唯一需要改变的是改变

 request.ContentLength = clientRequest.InputStream.Length; 

 request.ContentLength = clientRequest.ContentLength; 

前者在整个请求stream中确定内容的长度; 后者仅仅检查Content-Length头,只需要头已经被完整地发送。 这使IIS可以立即开始stream式传输请求,这完全消除了原来的问题。

当然,你可以做到这一点。 请参阅使用HttpWebRequest和IHttpHandler进行RESTfulfile upload 。 我已经使用这种方法几年,并有一个网站已经testing了至less几个千兆字节的文件。 本质上,你想创build自己的IHttpHandler,这比听起来容易。

简而言之,您将创build一个实现IHttpHandler接口的类,这意味着您必须支持IsReusable属性和ProcessRequest方法。 最重要的是,你的web.config有一个小的改变,它就像一个魅力。 在请求的生命周期的这个阶段,上传的整个文件不会被加载到内存中,因此它整齐地解决了内存不足的问题。

请注意,在web.config中,

 <httpHandlers> <add verb="*" path="DocumentUploadService.upl" validate="false" type="TestUploadService.FileUploadHandler, TestUploadService"/> </httpHandlers> 

引用的文件DocumentUploadService.upl实际上并不存在。 这只是在那里给一个替代的扩展,以便该请求不被标准处理程序拦截。 您将file upload表单指向该path,然后您的FileUploadHandler类将启动并实际接收该文件。

更新:其实,我使用的代码是不同的文章,我想我偶然发现它的原因。 我使用HttpPostedFile类,其中“文件以MIME multipart / form-data格式上传。默认情况下,大于256 KB的所有请求(包括表单字段和上传文件)都caching到磁盘,而不是保存在服务器内存中。 “

 if (context.Request.Files.Count > 0) { string tempFile = context.Request.PhysicalApplicationPath; for(int i = 0; i < context.Request.Files.Count; i++) { HttpPostedFile uploadFile = context.Request.Files[i]; if (uploadFile.ContentLength > 0) { uploadFile.SaveAs(string.Format("{0}{1}{2}", tempFile,"Upload\\", uploadFile.FileName)); } } }