带有“validateAllProperties”的Validator.ValidateObject为true,在第一次出错时停止

时间:2011-04-12 14:35:44

标签: c# validation c#-4.0

我有一个自定义类(简单来说):

using System;
using System.ComponentModel.DataAnnotations;

public class MyClass {
    [Required]
    public string Title { get; set;}
    [Required]
    public string Description { get; set;}
}

我想验证这个对象,并获得一个不正确的异常。

如果我这样做:

void Validate() {
    var objectToValidate = new MyClass { }; // Both properties are null at this time
    var ctx = new ValidationContext(objectToValidate, null, null);
    Validator.ValidateObject(objectToValidate, ctx, true);
}

抛出ValidationException但它只显示第一个错误,即使我为validateAllProperties参数指定了true。

如果我重构一下我的代码:

void Validate() {
    var objectToValidate = new MyClass { }; // Both properties are null at this time
    var ctx = new ValidationContext(objectToValidate, null, null);
    var errors = new List<ValidationResult>();
    var isValid = Validator.TryValidateObject(objectToValidate, ctx, errors, true);

    if(!isValid) {
        throw new AggregateException(
            errors.Select((e)=>new ValidationException(e.ErrorMessage)
        );
    }
}

我实际上可以解决所有错误。

为什么第一个代码段按预期工作?我做错了吗?

THX

1 个答案:

答案 0 :(得分:13)

Validator.ValidateObject 会遍历所有验证属性,并针对第一个失败的属性抛出 ValidationException 。我不认为可以获得以这种方式失败的所有属性的列表。

MSDN文档在这里有点令人困惑,它说:

  

ValidateObject方法评估与对象类型关联的每个ValidationAttribute属性。如果validateAllProperties设置为true,则该方法验证对象的属性值

TryValidateObject方法手册继续:

  

它还会检查是否提供了标有RequiredAttribute的每个属性。

我确认无论validateAllProperties如何,它始终会检查所有必需属性。但是,如果您有一个Range验证属性,它只会在validateAllProperties为true时检查它(因为这是验证属性值时)。有点令人困惑,但正如您所注意到的, TryValidateObject 显示了所有失败的属性,这也是我正在为我的项目使用的。