Reputation: 1842
I removed the extra properties for simplicity sake but I am using a partial class for an entity model using a metadata type for validation. This has always worked fine for me in the past until I try and validate an HttpPostedFileBase object. The value is always null though the property gets set in the controller.
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddEvent(Event model, HttpPostedFileBase file)
{
if (file != null)
{
model.UploadedFile = file;
}
if (!ModelState.IsValid) return View(model);
model.Save();
return View(model);
}
Partial class:
[MetadataType(typeof(EventMeta))]
public partial class Event
{
public HttpPostedFileBase UploadedFile { get; set; }
}
EventMeta Class:
public class EventMeta
{
[FileValidation]
public HttpPostedFileBase UploadedFile { get; set; }
}
Custom Validation Attribute:
public sealed class FileValidation : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var file = value as HttpPostedFileBase;
if(file == null) <--Always null
return ValidationResult.Success;
try
{
var img = Image.FromStream(file.InputStream);
var format = img.RawFormat;
var codec = ImageCodecInfo.GetImageDecoders().First(c => c.FormatID == format.Guid);
var mimeType = codec.MimeType;
if(mimeType != "image/jpg")
return new ValidationResult("Please upload a valid JPG file");
}
catch
{
return new ValidationResult("Please upload a valid JPG file");
}
return ValidationResult.Success;
}
}
Upvotes: 2
Views: 2027
Reputation: 2982
You need to match the name of your HTML file input match the HttpPostedFileBase that has the Validator on it.
You should change your action method signature to:
public ActionResult AddEvent(Event model)
and make sure the file input's name in the form is exactly "UploadedFile":
<input type="file" name="UploadedFile">
The Event.UploadedFile and input named 'file' do not have matching names so MVC does not wire up the validation for you.
You are actually assigning the uploaded file manually after posting to get around this naming mismatch when you do if (file != null) { model.UploadedFile = file; }
, which you can do but the ModelState has already been determined at this point.
You can reevaluate the modelstate by using some old MVC2 methods like TryValidateModel()
but you probably shouldnt do that and should just make the names match instead.
Upvotes: 1