I went across some sort of limitation in ASP.NET. I reduced the problem into a sample project in ASP.NET MVC Project (created with Visual Studio 2010 and .NET 4) and the problem still occurs:
In a MVC Controller I have a method which provides a file download:
public ActionResult DownloadBigFile()
{
string file = @"C:\Temp\File.txt";
var readStream = new FileStream(file, FileMode.Open, FileAccess.Read);
return File(readStream, "text/plain", "FILE");
}
When the file is below 1 GB the download works fine, above 1 GB an exception is thrown: "Overflow or underflow in the arithmetic operation" with the following details:
Overflow or underflow in the arithmetic operation.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArithmeticException: Overflow or underflow in the arithmetic operation.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[ArithmeticException: Overflow or underflow in the arithmetic operation.]
[HttpException (0x80004005): An error occurred while communicating with the remote host. The error code is 0x80070216.]
System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError(Int32 result, Boolean throwOnDisconnect) +4081269
System.Web.Hosting.IIS7WorkerRequest.FlushCore(Boolean keepConnected, Int32 numBodyFragments, IntPtr[] bodyFragments, Int32[] bodyFragmentLengths, Int32[] bodyFragmentTypes) +12233777
System.Web.Hosting.IIS7WorkerRequest.FlushCachedResponse(Boolean isFinal) +847
System.Web.HttpResponse.UpdateNativeResponse(Boolean sendHeaders) +1110
System.Web.HttpRuntime.FinishRequestNotification(IIS7WorkerRequest wr, HttpContext context, RequestNotificationStatus& status) +336
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.34009
The problem is reproducible but I did not find any information about this behavior. How can I prevent this kind of problem or how can I manage big downloads (> 1GB)?
Disable buffering in IIS will do the job:
public ActionResult DownloadBigFile()
{
string file = @"C:\Temp\File.txt";
var readStream = new FileStream(file, FileMode.Open, FileAccess.Read);
Response.BufferOutput = false; //<-----
return File(readStream, "text/plain", "FILE");
}
It really beats me why this is not the default ASP.Net MVC behavior when returning files. Especially when doing it with streams.