- Not every operating system implements file name conventions the same way. Rather, we shouldn't assume that we know anything about the format of the file name we'll receive, it's just a string -- and it may be an empty string.
- We can't assume that the browser used to upload the file will accurately identify the content type of the uploaded file.
- The user may upload an image type that they recognize, but our web server does not recognize as an image.
public class UploadedFileModel
{
[Required, ImageType]
public HttpPostedFileBase Image { get; set; }
}
Pretty simple, just one property, nothing too fancy. If you're familiar with DataAnnotations, you'll recognize the Required validator right away. This just checks to see if the property is null when the model is bound to my action.The other thing one might notice is the ImageType attribute. This is where I put my secret sauce. Take a look:
At this point, I'm effectively asking the web server if it recognizes whether the posted file as an image type. Yes? Hooray! No? We'll tell the user that it didn't look like a valid image type to us.public class ImageTypeAttribute : ValidationAttribute { public override bool IsValid(object value) { // don't duplicate the Required validator if (value == null) return true; // is it the type we expect? if (!(value is HttpPostedFileBase)) return false; // We got this far, is it a recognizable image type? var fileStream = ((HttpPostedFileBase) value).InputStream; try { var image = Image.FromStream(fileStream); } catch { return false; } return true; } public override string FormatErrorMessage(string name) { return string.Format("{0} is not a valid image format.", name); } }
Once all that is wired up, we can let the action just do action stuff:
And that's pretty much it. I tried to take advantage of as much default behavior as I could, and I ended up with a validator that I can reuse.[AcceptVerbs(HttpVerbs.Post)] public ActionResult Insert(UploadedFileModel viewModel) { if (!ModelState.IsValid) return View("Create"); var model = ImageUtilities.SaveImage(viewModel.Image); if (model == null) { ModelState.AddModelError("Image", "File could not be saved, this could happen if the client did not have permission to save the file to disk."); return View("Create"); } repository.Add(model); return RedirectToAction("Details", new {id = model.Name}); }
1 comment:
This is awesome!! really helpful for me. Thanks for sharing with us. Following links also helped me to complete my task.
http://www.mindstick.com/Articles/0a636769-717f-408a-8070-659986d700b5/?Upload%20File%20using%20Model%20Validation%20in%20ASP%20NET%20MVC
http://stackoverflow.com/questions/6388812/how-to-validate-uploaded-file-in-asp-net-mvc
Post a Comment