I've created a WebAPI Controller - based on MVC 5 - that provides different files for our customers. The tool to access the files is also self written - based on .NET HttpClient - but thats an other story.
In the first version of the download controller I've used the build in mechanism to provide the files like this
But that mechanism crashed on my iis for files > 4GB.
So I finally came to this code:
public class DownloadController : ApiController
{
public async Task Get(long id)
{
string fullFilePath = GetFilePathById(id);
string returnFileName = fullFilePath.Split('\\').Last();
FileInfo path = new FileInfo(fullFilePath);
HttpContext.Current.Response.ContentType = "application/zip";
HttpContext.Current.Response.AddHeader("Content-Length", path.Length.ToString());
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + returnFileName);
HttpContext.Current.Response.Flush();
try
{
byte[] buffer = new byte[4096];
using (FileStream fs = path.OpenRead())
{
using (BufferedStream bs = new BufferedStream(fs, 524288))
{
int count = 0;
while ((count = bs.Read(buffer, 0, buffer.Length)) > 0)
{
if (!HttpContext.Current.Response.IsClientConnected)
{
break;
}
HttpContext.Current.Response.OutputStream.Write(buffer, 0, count);
HttpContext.Current.Response.Flush();
}
}
}
}
catch (Exception exception)
{
//Exception logging here
}
}
}
That code works very well and I got fast downloads with acceptable CPU usage and disk i/o. But after some time I noticed that - with every single download - an unhandled exception writes an entry into the Application Eventlog of the IIS server like this:
Server cannot set status after HTTP headers have been sent
Exception type: HttpException
Event Log ID 1309
I'm sure that the recurring use of .Flush() causes the problem, but if I remove any of these the download stops working.
In similar questions I can find Response.BufferOutput = true;
as a solution but that seems to eat all my server resources and delays the download.
Any suggestions would be great!