1

Basically I have a page with a file input that allows end-users to upload some document.

I have a controller which looks like this

public class MyController : Controller 
{
  [HttpPost]
  public ActionResult MyAction(MyViewModel model, HttpPostedFileBase document)
  { .. }
}

What I want to achieve is: when a user attempts to upload a file that is larger than the maxContentLength setting allows a validation error should be added to the ModelState and the user should be returned to the page where the form he submitted was. Handling the error in an ExceptionFilter and redirecting to a custom page isn't a solution.

DenisPostu
  • 599
  • 3
  • 10

1 Answers1

3

You can't send requests that are larger than the maxContentLength setting. The web server will kill this request much before it had even chance to reach your application and give you the possibility to handle this error. So if you want to handle it you will have to increase the value of maxContentLength to a reasonably large number and then inside your controller action check for the ContentLength of the uploaded file.

[HttpPost]
public ActionResult MyAction(MyViewModel model, HttpPostedFileBase document)
{ 
    if (document != null && document.ContentLength > MAX_ALLOWED_SIZE)
    {
        ModelState.AddModelError("document", "your file size exceeds the maximum allowed file size")
        return View(model);
    }

    ...
}

But obviously a much cleaner solution is to directly handle this at your view model. You don't need a HttpPostedFileBase argument. That's what view models are intended for:

public class MyViewModel
{ 
    [MaxFileSize(MAX_ALLOWED_SIZE)]
    public HttpPostedFileBase Document { get; set; }

    ... some other properties and stuff
}

where MaxFileSize is obviously a custom attribute that you could easily implement.

And now your POST action becomes more standard:

[HttpPost]
public ActionResult MyAction(MyViewModel model)
{ 
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    ...
}

You may take a look at the following example I wrote.

Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Another thing I attempted was: when the user changes the value of the file input I start an async upload to the server. If the async upload fails - I disallow the user to submit the parent form, if the async upload succeeds (HTTP 200 recieved) I will allow him to submit the form assuming that the second upload will also succeed. – DenisPostu Jul 09 '12 at 13:11
  • Darin, your example helped me a lot. There's something else to mention: if the content length is greater that the one specified in the web.config with or the server will return a response code of 404.13 which can be missleading sometimes. – DenisPostu Jul 10 '12 at 11:09