为了简单起见,我删除了额外的属性,但是我使用元数据类型进行验证的实体模型的部分类。在我尝试验证HttpPostedFileBase对象之前,这对我来说一直很好。尽管在控制器中设置了属性,但该值始终为null。
控制器:
[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);
}
部分课程:
[MetadataType(typeof(EventMeta))]
public partial class Event
{
public HttpPostedFileBase UploadedFile { get; set; }
}
EventMeta类:
public class EventMeta
{
[FileValidation]
public HttpPostedFileBase UploadedFile { get; set; }
}
自定义验证属性:
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;
}
}
答案 0 :(得分:1)
您需要匹配HTML文件输入的名称与匹配有Validator的HttpPostedFileBase匹配。
您应该将操作方法签名更改为:
public ActionResult AddEvent(Event model)
并确保表单中的文件输入名称正好是#34; UploadedFile&#34;:
<input type="file" name="UploadedFile">
Event.UploadedFile并输入名为&#39;的文件&#39;没有匹配的名称,因此MVC不会为您连接验证。
您实际上是在发布后手动分配上传的文件,以便在执行if (file != null) { model.UploadedFile = file; }
时解决此命名不匹配问题,您可以执行此操作,但此时已确定ModelState。
您可以使用一些旧的MVC2方法(例如TryValidateModel()
)重新评估模型状态,但您可能不应该这样做,而应该只是使名称匹配。