0

I have a file upload page which on button click I am calling one method where I define the maximum size to be 5 MB. But when I upload more than that, the size error message is not displaying. Here is my code:

public ActionResult document(HttpPostedFileBase file, Document model)
{
    tbldocument doc = new tbldocument();
    //Document model = new Document();
    doc.DocumentName = model.documentname;

    if (ModelState.IsValid)
    {
        if (file == null)
        {
            ModelState.AddModelError("File", "Please Upload Your file");
        }
        else if (file.ContentLength > 0)
        {
            int MaxContentLength = 1024 * 1024 * 10; //10 MB
            string[] AllowedFileExtensions = new string[] { ".jpg", ".gif", ".png", ".pdf", ".docx", ".doc", ".xml", ".odt", ".xlsx", ".ppt" };

            if (!AllowedFileExtensions.Contains(file.FileName.Substring(file.FileName.LastIndexOf('.'))))
            {
                ModelState.AddModelError("File", "Please file of type: " + string.Join(", ", AllowedFileExtensions));
            }

            else if (file.ContentLength > MaxContentLength)
            {
                ModelState.AddModelError("File", "Your file is too large, maximum allowed size is: " + MaxContentLength + " MB");
            }
            else
            {
                var fileName = Path.GetFileName(file.FileName);
                var path = Server.MapPath("~/App_Data/uploads/documents/" + model.projectid + "");
                //var pathFile = path + fileName;
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                var pathWithfileName = Path.Combine(path, fileName);
                file.SaveAs(pathWithfileName);
                ModelState.Clear();
                tbldocument objdb = new tbldocument();
                objdb.DocumentName = model.documentname;
                objdb.ProjectId = model.projectid;
                objdb.Path = model.path;
                objdb.Path = Convert.ToString(pathWithfileName);
                // objdb.FileName = file.FileName;
                //objdb.FileName = file.FileName;
                objdoc.upload(objdb);
                //" + projectid + "
                ViewBag.Message = "File uploaded successfully. File path : ~/Upload/" + fileName;
            }
        }
    }
    return RedirectToAction("ProjectTask", "TblTask");
}

Here is the snap enter image description here. Instead of showing the message to the user that the file must be smaller than 5 MB, it throws an error like:

Enter image description here

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Muhafil Saiyed
  • 230
  • 1
  • 20
  • 1
    Thank you for Edit @Stephen Muecke – Muhafil Saiyed Apr 06 '16 at 05:27
  • Is that method marked with `[HttpPost]`? And nowhere in your code you you ever return the view (your just redirect) so adding `ModelSateError` and `ViewBag` properties is a bit pointless –  Apr 06 '16 at 05:28
  • 1
    Then should i return model instead or file ? i redirect because when user click on upload i will redirect to document list or project list not on same page – Muhafil Saiyed Apr 06 '16 at 05:31
  • 1
    i changed to return view from redirect but same error – Muhafil Saiyed Apr 06 '16 at 05:33
  • See the other answers for the possible solution. My comment was relating to other errors in your code. If you add a ModelStateError`, then you need to check again for `ModelState` is invalid, and if so, return the view (and you cannot call `ModelState.Clear();` because that just clears all the errors you just added) –  Apr 06 '16 at 05:36

2 Answers2

0

Since the upload is stored in IIS RAM until the file is fully uploaded, IIS will barf when the file is too big before ever calling your method. If you'd like large files uploaded, add something like this to web.config:

<system.webServer>
    <security>
        <requestFiltering>
            <requestLimits maxAllowedContentLength="104857600" /><!-- bytes -->
        </requestFiltering>
    </security>
</system.webServer>

And if you'd like to handle these "unhandled" errors more elegantly, add a Application_Error method in global.asax.cs.

robrich
  • 13,017
  • 7
  • 36
  • 63
0

You might be running into the default request limit in ASP.NET which is: 4MB (docs).

From: http://www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api/

Additionally, ASP.NET runtime has its own file size limit (which was also used by IIS 6, so if you use that version, that’s the only place you need to modify) – located under the httpRuntime element of the web.config.

By default it’s set to 4MB (4096kB). You need to change that as well (it’s set in kB not in bytes as the previous one!):

<system.web>
  <httpRuntime maxRequestLength="2097152" />
</system.web>

It’s worth remembering, that out of the two configuration elements, whichever request length limit is smaller, will take precedence.

Further, given that you host your application inside IIS 7 or newer, you should also remember to adjust the maxAllowedContentLength as well (this setting is used by IIS). The default value of this, is 30000000 bytes (~28.6 MB) (docs).

I can encourage you to take a look at: http://www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api/ - that article covers how to work with large files in ASP.NET, very well.

Lasse Christiansen
  • 10,205
  • 7
  • 50
  • 79
  • 1
    didn't get you sir can you @Lasse Christiansen Tell me what exactly i can do ? – Muhafil Saiyed Apr 06 '16 at 05:36
  • `...` is for IIS 7+. Unless you're on Win XP or Server 2003, this solution probably won't help you anymore. – robrich Apr 06 '16 at 05:38
  • @robrich Thanks for your comment :) I was wondering if you have some documentation that states that `httpRuntime` is for IIS 6 and downwards? As I understand it, IIS 7+ has its own setting (`maxAllowedContentLength`) whereas ASP.NET still relies on `maxRequestLength`? The difference is, as I understand it, that IIS 6 used the same setting as ASP.NET. I might be wrong, though :) – Lasse Christiansen Apr 06 '16 at 05:56
  • Thanks @robrich - as I read it, that does not say that `httpRuntime` is not required / used by ASP.NET? :) As seen in other places, like here: http://stackoverflow.com/a/3853785/700926 - both values must be present in order to configure both IIS and ASP.NET. Or am I missing something? :) – Lasse Christiansen Apr 06 '16 at 06:06
  • The way I read it was all things IIS and/or ASP.NET used in were replaced in IIS 7 by things in , and both IIS and ASP.NET started reading them there. Did I read it wrong? Alas, I usually set both places together with meaning "don't barf at the duplication". – robrich Apr 06 '16 at 06:15
  • @robrich I did not manage to quickly find any docs from MSDN on the topic, but based on what I can read from http://stackoverflow.com/a/3853785/700926 and http://stackoverflow.com/a/6472631/700926 both values need to be set to configure both IIS and ASP.NET - with the lowest value taking priority :) Thanks for the chat - it is always a good exercise to dive into details from time to time :) – Lasse Christiansen Apr 06 '16 at 06:25