实体框架中的多组验证

时间:2014-01-14 03:54:59

标签: entity-framework validation

我遇到了这个问题,我在保存模型时应该允许不同的验证集。通常,验证取决于用户想要如何保存数据。例如,如果用户想要将他的数据保存为" 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中正确创建条件验证?

1 个答案:

答案 0 :(得分:1)

数据注释不仅用于验证,还用于使代码与数据库同步。即在EF代码中,如果删除必填字段,则数据库必须允许在匹配列中插入NULL。

因此,您可以采取以下方法:

  1. 创建实体模型类以使其具有尽可能低的要求
  2. 创建将实现IValidatableObject接口的视图/ DTO模型类
  3. 实现IValidatableObject接口并在那里进行条件验证
  4. 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);
        }
    }