【问题标题】:FilePathResult thrown an OutOfMemoryException with large fileFilePathResult 引发了带有大文件的 OutOfMemoryException
【发布时间】:2013-11-29 09:43:31
【问题描述】:

我的控制器中有这个动作,它向用户返回一个文件。

public virtual ActionResult ReturnFile(string fileName, string filePath, string contentType)
{
    var cd = new System.Net.Mime.ContentDisposition
    {
        FileName = fileName,

        // always prompt the user for downloading, set to true if you want 
        // the browser to try to show the file inline
        Inline = false,
    };

    // set token for close the modal-window
    CookiesHelper.SetValueDownloadTokenInCookie();
    Response.AppendHeader("Content-Disposition", cd.ToString());
    return File(filePath, contentType);
}

它工作正常,但问题是当文件很大(略大于 220 Mb)时,它会抛出一个OutOfMemoryException

这是堆栈跟踪

[OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.]
   System.IO.MemoryStream.set_Capacity(Int32 value) +93
   System.IO.MemoryStream.EnsureCapacity(Int32 value) +64
   System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) +330
   Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.ArteryFilter.Write(Byte[] buffer, Int32 offset, Int32 count) +106
   System.Web.HttpWriter.FilterIntegrated(Boolean finalFiltering, IIS7WorkerRequest wr) +9509748
   System.Web.HttpResponse.FilterOutput() +104
   System.Web.CallFilterExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +49
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69

有什么想法吗?

【问题讨论】:

  • 这很奇怪,因为FilePathResult 正在使用HttpResponse.TransmitFile,它不会缓冲文件。你确定这是异常来自的动作吗?附言你不需要设置Content-Disposition,结果会为你做。

标签: c# asp.net-mvc


【解决方案1】:

这是因为您的请求使用了PageInspector,正如堆栈跟踪的这一行所示:

Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.ArteryFilter.Write(Byte[] buffer, Int32 offset, Int32 count) +106

要解决此问题,请取消选中 Visual Studio 中的浏览器复选框,如以下屏幕截图所示:

【讨论】:

  • 非常感谢您的帮助 - 救星!我被困了 2 天,试图下载大文件;所有其他解决方案都指向 IIS、Web.Config、FileStreams 等,但没有任何效果。这是 100% 正确的 - 浏览器链接正在干扰。旁注:有没有办法只为下载页面以编程方式禁用浏览器链接,例如在页眉中?我想让它在开发时在项目的其余部分处于活动状态,而不需要一直打开和关闭它?
  • 更新我上面的 Broswer Link 问题 - 不是 100% 我想要的,但如果其他人感兴趣:stackoverflow.com/questions/27432670/…
【解决方案2】:

我认为您可以通过在 Web.config 文件中设置 maxQueryString 来解决问题。如果你还没有设置,看看下面的代码:

 <system.webServer>
   <security>
      <requestFiltering>
        <requestLimits maxUrl="10999" maxQueryString="9999" />
      </requestFiltering>
    </security>
 </system.webServer>

您可以根据需要设置最大值。

【讨论】:

  • 请注意,该值有上限 - 最大值为 4,294,967,295 字节(uint 的最大值)。
  • 是的,是的;只是想指出它是有限制的,以防有人出现,看看你的答案,然后尝试一些无效的大数字。
  • 嗨@Tim,我明白你的意思了。我认为您的建议会有所帮助。
  • 嗨@sabotero,我回答了你的问题。我不确定你的文件路径是什么样的,我添加了 maxUrl 你可以再试一次。让我知道它是否适合你。
  • @Lin 谢谢你的回答,我试过了,可惜没用。我添加了 Stack Trace 以获取更多详细信息。我不明白为什么我会收到这个错误。因为通常FilePathResult 使用的是HttpResponse.TransmitFile
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-02
  • 2014-06-06
  • 2013-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多