Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validator.ValidateObject with "validateAllProperties" to true stop at first error

I have a custom class (to be simple) :

using System;
using System.ComponentModel.DataAnnotations;

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

I want to validate this object, and get an exception with everything not correct.

If I do :

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);
}

A ValidationException is thrown but it shows only the first error, even I specify true to the validateAllProperties parameter.

if I refactor a bit my code :

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)
        );
    }
}

I can actually have all my errors.

Why does the first code snippet works as expected ? Did I do something wrong?

like image 426
Steve B Avatar asked Apr 12 '11 14:04

Steve B


1 Answers

Validator.ValidateObject goes through all validation attributes and throws ValidationException for the first one that fails. I don't think one can get the list of all properties that failed this way.

The MSDN documentation is a bit confusing here, it says:

The ValidateObject method evaluates each ValidationAttribute attribute that is associated with the object type. If validateAllProperties is set to true, the method validates the property values of the object.

TryValidateObject method manual continues:

It also checks whether each property that is marked with RequiredAttribute is provided.

I confirm that it always checks all the Required attributes, regardless of validateAllProperties. But if you have, for example, a Range validation attribute it will only check it when validateAllProperties is true (because this is when it validates the property value). A bit confusing, but as you noticed, TryValidateObject shows all the failed properties and this is what I'm using for my project as well.

like image 66
Evgenii Avatar answered Oct 29 '22 14:10

Evgenii