3

I'm getting this error when uploading a file that is 84MB (see error below) but when I upload a ~60MB file, it works fine. This only occurs on our 32bit 2008 VM w/ 4GB memory. On my R2 64bit VM w/8GB memory, it works fine with even 130MB file.

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. at System.IO.BinaryReader.ReadBytes(Int32 count) at CustWeb.Controllers.DownloadsController.Create(Download dl, HttpPostedFileBase file) in c:\...\CustWeb\Controllers\DownloadsController.cs:line 72

I monitored the Memory in the task manager, though, and it never goes above 74% during the entire upload process.

This is an MVC 4 application on the 4.5 .NET framework.

I have the max settings in my web.config in dealing with uploading files.

<httpRuntime requestValidationMode="4.5" targetFramework="4.5" maxRequestLength="2147483647" executionTimeout="84000" />

...

<security>
     <requestFiltering>
         <requestLimits maxAllowedContentLength="2147482624" />
     </requestFiltering> 
</security>

UPDATE Adding code as requested:

    public ActionResult Create(Download dl, HttpPostedFileBase file)
    {
        try
        {
            using (var binaryReader = new BinaryReader(file.InputStream))
            {
                dl.FileBytes = binaryReader.ReadBytes(file.ContentLength);
            }
            dl.FileContentType = file.ContentType;
            dl.FileName = file.FileName;
            dl.Insert();
            Success("<strong>" + dl.Label + "</strong> created and uploaded successfully.");
            return RedirectToAction("Index");
        }
        catch (Exception ex)
        {
            SelectList list = new SelectList(new DownloadType().GetDownloadTypes(), "ID", "Name");
            ViewBag.DownloadTypeList = list;
            Error(ex.ToString());
            return View(dl);
        }
    }
4
  • Using a BinaryReader here is wrong. Commented Jun 3, 2013 at 21:26
  • @SLaks - added my code as you requested. Commented Jun 4, 2013 at 12:42
  • @leppie I added my code - is there a better way to do what I'm doing than using the BinaryReader? Commented Jun 4, 2013 at 12:44
  • @leppie - I changed it from BinaryReader to just using MemoryStream and I still get the same error. Commented Jun 5, 2013 at 15:16

2 Answers 2

3

By default ASP.NET is allowed 60% of available memory - check memoryLimit in processModel in machine.config. You can change that value to, say 80% to give ASP.NET more room, but this is not recommend. Consider other options, like uploading file in chunks etc.

Sign up to request clarification or add additional context in comments.

4 Comments

Wow - how do you upload files in chunks?
There are different way from using HTTP Modules e.g: dotnetslackers.com/Community/blogs/haissam/archive/2008/09/12/… to using 3rd party controls e.g. plupload.com. But even before that try playing with requestLengthDiskThreshold attribute of httpRuntime section of web.config you've shown above. It controls the size of the uploaded file that server can hold in memory before caching it to disk.
The default appears to be 256 bytes to prevent using too much memory. it seems like increasing it would use even more memory and make the problem worse, no?
For .NET 4.5 default is 80 kilobytes, but you're right increasing would make it worse. Never mind this property then, unfortunately it won't help you. My thought was if default is to large - try to decrease it, but that is not the case
0

I changed it from stream to file.SaveAs and that prevented the memory error.

    public ActionResult Create(Download dl, HttpPostedFileBase file)
    {
        try
        {
            string tempFile = Path.Combine(Server.MapPath("~/App_Data/"), string.Format("{0}_{1}",Guid.NewGuid().ToString(), Path.GetFileName(file.FileName)));
            file.SaveAs(tempFile);
            dl.FileBytes = System.IO.File.ReadAllBytes(tempFile);
            dl.FileContentType = file.ContentType;
            dl.FileName = file.FileName;
            dl.Insert();
            System.IO.File.Delete(tempFile);
            Success("<strong>" + dl.Label + "</strong> created and uploaded successfully.");
            return RedirectToAction("Index");
        }
        catch (Exception ex)
        {
            SelectList list = new SelectList(new DownloadType().GetDownloadTypes(), "ID", "Name");
            ViewBag.DownloadTypeList = list;
            Error(ex.ToString());
            return View(dl);
        }
    }

2 Comments

I still occasionally get the memory errors but changing it to this method definitely improved (doubled) the filesize that I am able to upload. I'll have to increase the actual RAM to do better than a 160MB file, I guess.
After doing some reading on this subject. My issue isn't the uploading of the file, it's the readAllBytes before saving it to the database. It also looks like if I'm going to be possibly saving 200MB+ files, I should instead store those in the file system and save the reference to the DB.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.