Validator.ValidateObject с "validateAllProperties" до истинной остановки при первой ошибке

У меня есть собственный класс (простой):

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, но оно показывает только первую ошибку, даже я указываю true для параметра validateAllProperties.

Если я немного реорганизую свой код:

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

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

У меня могут быть все мои ошибки.

Почему первый фрагмент кода работает так, как ожидалось? Я сделал что-то неправильно?

ТНХ

Ответ 1

Validator.ValidateObject просматривает все атрибуты проверки и выбрасывает ValidationException для первого, который терпит неудачу. Я не думаю, что можно получить список всех свойств, которые провалились таким образом.

Документация MSDN здесь немного запутанна, она гласит:

Метод ValidateObject оценивает каждый атрибут ValidationAttribute, который связан с типом объекта. Если для validateAllProperties установлено значение true, метод проверяет значения свойств объекта.

Руководство по методу TryValidateObject продолжается:

Он также проверяет, предоставлено ли каждое свойство, помеченное RequiredAttribute.

Я подтверждаю, что он всегда проверяет все необходимые атрибуты, независимо от validateAllProperties. Но если у вас есть, например, атрибут проверки диапазона, он будет проверять его только тогда, когда validateAllProperties является истинным (потому что это когда проверяет значение свойства). Немного сбивает с толку, но, как вы заметили, TryValidateObject показывает все неудачные свойства, и это то, что я использую для моего проекта.