开发者

ASP.NET MVC: Handling upload exceeding maxRequestLength

When uploading a file in my MVC site, I'm looking to handle upload failures due to the user exceeding maxRequestLength more gracefully than for example showing a generic custom error page. I would prefer to display the same page they're trying to post to, but with a message informing开发者_开发技巧 them that their file was too large... similar to what they might get on a validation error.

I'm starting with the idea from this question:

Catching "Maximum request length exceeded"

BUT what I want to do is instead of Transferring to an error page (as they do in that question), I want to hand processing off to the original controller but with an error added to ModelState indicating the issue. Here's some code, with the comments indicating where and what I would like to do. See the question above for definition of IsMaxRequestExceededEexception, which is a bit of a hack, but I haven't found much better.

The line I've commented out returns the user to the right page, but of course they lose any changes they may have made and I don't want to use Redirect here...

if (IsMaxRequestExceededException(Server.GetLastError()))
{
    Server.ClearError();
    //((HttpApplication) sender).Context.Response.Redirect(Request.Url.LocalPath + "?maxLengthExceeded=true");
    // TODO: Replace above line - instead tranfer processing to appropriate controlller with context intact, etc
    // but with an extra error added to ModelState.
}

Just looking for ideas rather than a full solution; is what I'm trying to do is even possible?


Here's a workaround: set the maxRequestLength property in your web.config to some high value. Then write a custom validation attribute:

public class MaxFileSize : ValidationAttribute
{
    public int MaxSize { get; private set; }

    public MaxFileSize(int maxSize)
    {
        MaxSize = maxSize;
    }

    public override bool IsValid(object value)
    {
        var file = value as HttpPostedFileBase;
        if (file != null)
        {
            return file.ContentLength < MaxSize;
        }
        return true;
    } 
}

which could be used to decorate your view model with:

public class MyViewModel
{
    [Required]
    [MaxFileSize(1024 * 1024, ErrorMessage = "The uploaded file size must not exceed 1MB")]
    public HttpPostedFileBase File { get; set; }
}

then you could have a controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel();
        return View(model);
    }

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

        // TODO: Process the uploaded file: model.File

        return RedirectToAction("Success");
    }
}

and finally a view:

@model MyViewModel

@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <div>
       @Html.LabelFor(x => x.File)
       <input type="file" name="file" />
       @Html.ValidationMessageFor(x => x.File)
    </div>

    <p><input type="submit" value="Upload"></p>
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜