我遇到了这个问题,我在保存模型时应该允许不同的验证集。通常,验证取决于用户想要如何保存数据。例如,如果用户想要将他的数据保存为" Draft",我应该允许某些字段为空。如果不是"草案",我应该加入更多限制。
class Form
{
public int ID { get; set; }
[Required("Title is required.")]
public string Title { get; set; }
[Required("Body is required.")]
public string Body { get; set; }
public bool IsDraft { get; set; }
}
在上面的代码中,我希望body的验证仅在IsDraft为false时才能工作。
如何创建多组验证?或者如何在Entity Framework中正确创建条件验证?
答案 0 :(得分:1)
数据注释不仅用于验证,还用于使代码与数据库同步。即在EF代码中,如果删除必填字段,则数据库必须允许在匹配列中插入NULL。
因此,您可以采取以下方法:
IValidatableObject接口允许您的类由System.ComponentModel.DataAnnotations命名空间中的Validator(MSDN on Validator)使用,就像通过注释属性进行验证一样。
接口实现应如下所示:
public class FormDto: IValidatableObject
{
public int ID { get; set; }
[Required("Title is required.")]
public string Title { get; set; }
[Required("Body is required.")]
public string Body { get; set; }
public bool IsDraft { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(!IsDraft && string.IsNullOrWhiteSpace(Body)) yield return new ValidationResult("Body is required.", new string [] {"Body"});
if(!IsDraft && string.IsNullOrWhiteSpace(Title)) yield return new ValidationResult("Title is required.", new string [] {"Title"});
}
}
如果您的view / DTO模型正在通过MVC管道,则将自动调用此接口。如果由于任何原因你发现它没有被调用(我不知道你的解决方案的结构),你可以在流程管道中的某处插入这个代码,它将调用验证/抛出异常:
public static class IValidatableObjectExtensions
{
public static void SelfValidate(this IValidatableObject model)
{
ValidationContext ctx = new ValidationContext(model);
Validator.ValidateObject(model, ctx, true);
}
}