ASP.NET MVC:处理上传超过maxRequestLength

时间:2011-08-05 05:58:49

标签: asp.net-mvc file-upload

在我的MVC网站上传文件时,我希望处理上传失败,因为用户超出了maxRequestLength,比例如显示通用自定义错误页面更优雅。我希望显示他们尝试发布的同一页面,但是会显示一条消息,告知他们他们的文件太大了......类似于他们可能在验证错误上获得的内容。

我从这个问题的想法开始:

Catching "Maximum request length exceeded"

但是我想要做的不是转移到错误页面(就像他们在那个问题中那样),我想把处理交给原始控制器,但是添加到ModelState的错误表明问题。这是一些代码,其中的注释表明我想要做什么和做什么。请参阅上面的问题,了解IsMaxRequestExceededEexception的定义,这有点像黑客,但我找不到更好的。

我评论过的行将用户返回到正确的页面,但当然他们会丢失他们可能做出的任何更改,我不想在此处使用重定向...

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.
}

只是寻找想法而不是完整的解决方案;我试图做的甚至可能吗?

1 个答案:

答案 0 :(得分:0)

以下是一种解决方法:将web.config中的maxRequestLength属性设置为某个高值。然后编写自定义验证属性:

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;
    } 
}

可用于装饰您的视图模型:

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

然后你可以有一个控制器:

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");
    }
}

最后一个观点:

@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>
}