问题 EF Code First:IValidatable Object未验证


我在一个简单的测试场景中有一个对象,它使用EF Code First并实现IValidatableObject。有一些非常简单的逻辑可以添加验证错误并将其返回。对象上还有其他验证。

但是,在保存对象时 - 基于属性的验证工作 - IValidatableObject接口似乎永远不会触发。调试器不会进入它,并且调用SaveChanges()或GetValidationErrors()时错误永远不会出现。

public class Customer : IValidatableObject {
[Key]
public int Id { get; set; }

[StringLength(50)]
[DisplayName("First Name")]

public string FirstName { get; set; }

[Required]
[DisplayName("Last Name")]
[StringLength(50)]
public string LastName { get; set; }

[Required]
[StringLength(100)]
public string Company { get; set; }

[StringLength(200)]
public string Email { get; set; }

[DisplayName("Credit Limit")]
public decimal CreditLimit { get; set; }

[DisplayName("Entered On")]
public DateTime? Entered { get; set; }


public virtual ICollection<Address> Addresses { get; set;  }


public Customer()
{
    Entered = DateTime.Now;
    CreditLimit = 1000.00M;

    Addresses = new List<Address>();
}

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    var results = new List<ValidationResult>();

    // add an error ALWAYS for testing - it doesn't show up
    // and the debugger never hits this code
    results.Add(new ValidationResult("Validate Added message",new [] { "Company" }));

    return results;
}

当我现在尝试添加客户并检查验证错误时:

public void AddNewCustomer()
{
    Customer customer = new Customer();  

    context.Customers.Add(customer);

    customer.LastName = "Strahl";
    customer.FirstName = "Rick";
    customer.Entered = DateTime.Now;
    //customer.Company = "West Wind"; // missing causes val error

    var errorEntries = context.GetValidationErrors();
}

我得到了公司的一个验证错误,但IValidatableObject中的任何内容都应该总是失败。

知道为什么吗?


9682
2018-02-27 09:04


起源



答案:


引用自 Jeff Handley关于使用Validator验证对象和属性的博客文章

验证对象时,   以下过程适用于   Validator.ValidateObject:

  1. 验证属性级属性
  2. 如果任何验证器无效,则中止验证返回   失败(S)
  3. 验证对象级属性
  4. 如果任何验证器无效,则中止验证返回   失败(S)
  5. 如果在桌面框架和对象上实现   IValidatableObject,然后调用它   验证方法并返回任何方法   失败(S)

这表明您尝试做的事情不会开箱即用,因为验证将在步骤#2中止。


11
2018-02-27 09:29



是的,就是这样。如果没有其他验证错误,则会触发IValidatableObject代码。不过对这种行为不满意 - 不向用户显示适用的所有错误是很麻烦的。 - Rick Strahl
@Rick - 我同意。这可能是过早优化的情况...... - Jakub Konecki


答案:


引用自 Jeff Handley关于使用Validator验证对象和属性的博客文章

验证对象时,   以下过程适用于   Validator.ValidateObject:

  1. 验证属性级属性
  2. 如果任何验证器无效,则中止验证返回   失败(S)
  3. 验证对象级属性
  4. 如果任何验证器无效,则中止验证返回   失败(S)
  5. 如果在桌面框架和对象上实现   IValidatableObject,然后调用它   验证方法并返回任何方法   失败(S)

这表明您尝试做的事情不会开箱即用,因为验证将在步骤#2中止。


11
2018-02-27 09:29



是的,就是这样。如果没有其他验证错误,则会触发IValidatableObject代码。不过对这种行为不满意 - 不向用户显示适用的所有错误是很麻烦的。 - Rick Strahl
@Rick - 我同意。这可能是过早优化的情况...... - Jakub Konecki