c# - 在 Response.Flush() 下载大文件时出现 ASP.NET MVC 错误

标签 c# asp.net asp.net-mvc large-files iis-8

我使用 ASP.NET MVC 5。我在 Controller 中有一个名为 Download() 的函数来提供用户请求文件。我必须将目录中的文件压缩并将其作为一个 zip 文件交付。这些文件很大(例如,需要支持 ~100 GB 下载)

这是我尝试使该功能起作用

    public ActionResult Download()
    {
        var fileName = Path.GetRandomFileName() + ".zip";
        using (var zip = new ZipFile(fileName))
        {
            zip.CompressionLevel = CompressionLevel.BestCompression;
            zip.UseZip64WhenSaving = Zip64Option.Always;

            zip.AddDirectory(Server.MapPath(directory));

            var output = new MemoryStream();
            //zip.Save(output);
            Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
            Response.Buffer = true;
            Response.BufferOutput = true;

            zip.Save(Response.OutputStream);
            Response.Flush();

            output.Seek(0, SeekOrigin.Begin);
            return File(output, "application/zip", "Compilation.zip");
        }
   }

文件和目录始终不变,在客户端中它只是一个按钮。

到目前为止,我已经用总计 < 1 GB 的文件对其进行了测试,它可以正常工作。但是,当文件总数 > 1 GB 时会抛出异常。我有这个异常(exception)

Not enough storage is available to process this command. 
(Exception from HRESULT: 0x80070008)
Source Error: 
Line 50:                    Response.Flush();

我想知道,我是否错过了 MVC web.config 设置或 IIS 管理器设置中的某些配置?或者这纯粹是一个实现问题,我应该实现 zip 文件/目录并以其他方式即时下载 zip 文件。

编辑:为了验证,我的磁盘仍然有足够的空间,所以我直觉上不知道为什么它提示没有足够的存储空间。

编辑 2:该函数通过使 Response.BufferOutput = false; 起作用。但是,在调用此函数时,这部分的结果是不再有缓存。频繁调用时可能会降低一些性能。我想知道存储错误是不是因为缓冲区大小。

PS:如果有帮助,这是堆栈跟踪:

[COMException (0x80070008): Not enough storage is available to process this command. (Exception from HRESULT: 0x80070008)]
[HttpException (0x80004005): An error occurred while communicating with the remote host. The error code is 0x80070008.]
   System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError(Int32 result, Boolean throwOnDisconnect) +3415687
   System.Web.Hosting.IIS7WorkerRequest.FlushCore(Boolean keepConnected, Int32 numBodyFragments, IntPtr[] bodyFragments, Int32[] bodyFragmentLengths, Int32[] bodyFragmentTypes) +9790118
   System.Web.Hosting.IIS7WorkerRequest.FlushCachedResponse(Boolean isFinal) +413
   System.Web.HttpResponse.UpdateNativeResponse(Boolean sendHeaders) +467
   System.Web.HttpResponse.Flush(Boolean finalFlush, Boolean async) +152
   System.Web.HttpResponse.Flush() +23
   System.Web.HttpResponseWrapper.Flush() +14
   Poort80SimpleApp.Controllers.HomeController.Download() in D:\SimpleApp\SimpleApp\Controllers\HomeController.cs:50
   lambda_method(Closure , ControllerBase , Object[] ) +101
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +59
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +435
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +60
   System.Web.Mvc.Async.ActionInvocation.InvokeSynchronousActionMethod() +76
   System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +36
   System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +73
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +136
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +102
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +49
   System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +117
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +323
   System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +44
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +47
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +136
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +102
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +50
   System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +72
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +185
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +133
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +56
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +40
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +34
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +133
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +56
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +37
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +44
   System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +39
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +62
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +133
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +56
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +37
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +39
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +39
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +39
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +133
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +56
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +37
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +40
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9742689
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

最佳答案

Response.BufferOutput = false;
return File(fileStream, contentType);

尝试使用此组合,这将有助于您下载。 这可能需要一段时间,但文件将下载成功。

关于c# - 在 Response.Flush() 下载大文件时出现 ASP.NET MVC 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35035888/

相关文章:

c# - Request.Cookies 为空

c# - 使用 Navmesh 和协程的基本 RTS 运动?

c# - 如何在 Controller 外使用 session

c# - 如何向 .NET 中的特定 IP/端口发送和接收 tcp 消息

c# - 服务器端错误的浏览器检测

c# - 如何在没有 NuGet 的情况下安装和设置 RESTSharp?

asp.net - 使用 SQL Server ERROR : "The LOAD DATA SQL construct or statement is not supported" 在 Visual Studio 中加载数据输入文件

javascript - 如何在 Sharepoint 中调试 JavaScript?

MVC中的css3pie,pie.htc文件放在哪里?

javascript - 单独的 js 文件 utf-8 在 ASP.NET MVC Razor 中不起作用