如何validationASP.NET MVC中上传的文件?

我有一个创build操作,需要一个实体对象和一个HttpPostedFileBase图像。 该图像不属于实体模型。

我可以将实体对象保存在数据库和磁盘中的文件,但我不知道如何validation这些业务规则:

  • 图像是必需的
  • 内容types必须是“image / png”
  • 不得超过1MB

自定义validation属性是一种方法:

public class ValidateFileAttribute : RequiredAttribute { public override bool IsValid(object value) { var file = value as HttpPostedFileBase; if (file == null) { return false; } if (file.ContentLength > 1 * 1024 * 1024) { return false; } try { using (var img = Image.FromStream(file.InputStream)) { return img.RawFormat.Equals(ImageFormat.Png); } } catch { } return false; } } 

然后应用于您的模型:

 public class MyViewModel { [ValidateFile(ErrorMessage = "Please select a PNG image smaller than 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); } // The uploaded image corresponds to our business rules => process it var fileName = Path.GetFileName(model.File.FileName); var path = Path.Combine(Server.MapPath("~/App_Data"), fileName); model.File.SaveAs(path); return Content("Thanks for uploading", "text/plain"); } } 

和观点:

 @model MyViewModel @using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) { @Html.LabelFor(x => x.File) <input type="file" name="@Html.NameFor(x => x.File)" id="@Html.IdFor(x => x.File)" /> @Html.ValidationMessageFor(x => x.File) <input type="submit" value="upload" /> } 

基于Darin Dimitrov的回答,我发现这个答案非常有帮助,我有一个修改后的版本,允许检查多个文件types,这是我最初寻找的。

 public override bool IsValid(object value) { bool isValid = false; var file = value as HttpPostedFileBase; if (file == null || file.ContentLength > 1 * 1024 * 1024) { return isValid; } if (IsFileTypeValid(file)) { isValid = true; } return isValid; } private bool IsFileTypeValid(HttpPostedFileBase file) { bool isValid = false; try { using (var img = Image.FromStream(file.InputStream)) { if (IsOneOfValidFormats(img.RawFormat)) { isValid = true; } } } catch { //Image is invalid } return isValid; } private bool IsOneOfValidFormats(ImageFormat rawFormat) { List<ImageFormat> formats = getValidFormats(); foreach (ImageFormat format in formats) { if(rawFormat.Equals(format)) { return true; } } return false; } private List<ImageFormat> getValidFormats() { List<ImageFormat> formats = new List<ImageFormat>(); formats.Add(ImageFormat.Png); formats.Add(ImageFormat.Jpeg); formats.Add(ImageFormat.Gif); //add types here return formats; } } 

这里有一个方法可以使用viewmodel来完成,在这里查看整个代码

用于大小和types的Asp.Net MVC文件validation使用FileSize和FileTypes创build如下所示的视图模型

 public class ValidateFiles { [FileSize(10240)] [FileTypes("doc,docx,xlsx")] public HttpPostedFileBase File { get; set; } } 

创build自定义属性

 public class FileSizeAttribute : ValidationAttribute { private readonly int _maxSize; public FileSizeAttribute(int maxSize) { _maxSize = maxSize; } //..... //..... } public class FileTypesAttribute : ValidationAttribute { private readonly List<string> _types; public FileTypesAttribute(string types) { _types = types.Split(',').ToList(); } //.... //... } 

您可能还想考虑将图像保存到数据库:

  using (MemoryStream mstream = new MemoryStream()) { if (context.Request.Browser.Browser == "IE") context.Request.Files[0].InputStream.CopyTo(mstream); else context.Request.InputStream.CopyTo(mstream); if (ValidateIcon(mstream)) { Icon icon = new Icon() { ImageData = mstream.ToArray(), MimeType = context.Request.ContentType }; this.iconRepository.SaveOrUpdate(icon); } } 

我用这个与NHibernate – 实体定义:

  public Icon(int id, byte[] imageData, string mimeType) { this.Id = id; this.ImageData = imageData; this.MimeType = mimeType; } public virtual byte[] ImageData { get; set; } public virtual string MimeType { get; set; } 

然后,您可以将该图像作为FileContentResult返回:

  public FileContentResult GetIcon(int? iconId) { try { if (!iconId.HasValue) return null; Icon icon = this.iconRepository.Get(iconId.Value); return File(icon.ImageData, icon.MimeType); } catch (Exception ex) { Log.ErrorFormat("ImageController: GetIcon Critical Error: {0}", ex); return null; } } 

请注意,这是使用ajax提交。 否则更容易访问数据stream。