6

I have this Action in my controller which returns a file to the user.

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);
}

It is working fine, but the problem is that when the file is large (a little more than 220 Mb) it is throwing an OutOfMemoryException.

This is the Stack Trace

[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

Any ideas?

sabotero
  • 4,265
  • 3
  • 28
  • 43
  • Well this is weird as `FilePathResult` is using `HttpResponse.TransmitFile` which doesn't buffer the file. Are you sure that this the action that exception comes from? P.S. You don't need to set `Content-Disposition`, the result will do it for you. – tpeczek Nov 29 '13 at 11:06

2 Answers2

9

It is because your request is using PageInspector as indicated by this line of your stack trace:

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

To fix this, uncheck the browser checkbox in Visual Studio as in the following screen shot:

Uncheck Browser Link

rhughes
  • 9,257
  • 11
  • 59
  • 87
  • Thanks you so much for this - lifesaver! I've been stuck for 2 days trying to get large files to download; all other solutions point to IIS, Web.Config, FileStreams, etc. but nothing worked. This was 100% spot on - Browser Link was interfering. Side note: Is there a way to disable Browser Link programatically just for the download page, e.g. in page headers? I'd like to have it active for the rest of the project while developing and not need to toggle it on and off all the time? – AdrianD Feb 28 '16 at 08:23
  • Update to my above Broswer Link question - not 100% what I was looking for, but in case anyone else is interested: http://stackoverflow.com/questions/27432670/can-you-turn-off-visual-studio-2013-browser-link-on-a-page-by-page-basis – AdrianD Feb 28 '16 at 08:27
0

I think you can solve the problem by setting up maxQueryString in the Web.config file. If you have not set it up yet, take a look at below code:

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

You can set up the max value according to your needs.

Lin
  • 15,078
  • 4
  • 47
  • 49
  • Note that there is an upper limit for that value - max value is 4,294,967,295 bytes (max value for `uint`). – Tim Nov 29 '13 at 18:34
  • Yes, it is; just wanted to note that there is a limit to it, in case someone comes along, see's your answer and then tries some absurdly large number that doesn't work. – Tim Nov 29 '13 at 18:43
  • hi @Tim, I got what you mean now. I think your advice helps. – Lin Nov 29 '13 at 18:44
  • hi @sabotero, I answered your question. I'm not sure what is your file path looks like , I added maxUrl you can try it again. let me know if it works for you. – Lin Dec 02 '13 at 15:33
  • @Lin thank you for the answer, I tried it, unfortunatly did not work. I added the **Stack Trace** for more details. I don't understand why I'm getting this error. Because normally `FilePathResult` is using `HttpResponse.TransmitFile` – sabotero Dec 03 '13 at 08:46
  • Hello @Lin, I tried also: ` ` And did not work either. – sabotero Dec 03 '13 at 09:50