Streaming large file uploads to ASP.NET MVC

Benjamin Pollack picture Benjamin Pollack · Jun 25, 2009 · Viewed 21.4k times · Source

For an application I'm working on, I need to allow the user to upload very large files--i.e., potentially many gigabytes--via our website. Unfortunately, ASP.NET MVC appears to load the entire request into RAM before beginning to service it--not exactly ideal for such an application. Notably, trying to circumvent the issue via code such as the following:

if (request.Method == "POST")
{
    request.ContentLength = clientRequest.InputStream.Length;
    var rgbBody = new byte[32768];

    using (var requestStream = request.GetRequestStream())
    {
        int cbRead;
        while ((cbRead = clientRequest.InputStream.Read(rgbBody, 0, rgbBody.Length)) > 0)
        {
            fileStream.Write(rgbBody, 0, cbRead);
        }
    }
}

fails to circumvent the buffer-the-request-into-RAM mentality. Is there an easy way to work around this behavior?

Answer

Benjamin Pollack picture Benjamin Pollack · Aug 10, 2009

It turns out that my initial code was basically correct; the only change required was to change

request.ContentLength = clientRequest.InputStream.Length;

to

request.ContentLength = clientRequest.ContentLength;

The former streams in the entire request to determine the content length; the latter merely checks the Content-Length header, which only requires that the headers have been sent in full. This allows IIS to begin streaming the request almost immediately, which completely eliminates the original problem.