Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive validation using annotations and IValidatableObject

I am trying to validate nested objects (not models in the MVC senss) using annotations and some custom code.

I found the following post useful

Using Data Annotations Validation Manually and Object Graphs

As suggested in an answer, I've created an extra routine in the container class to validate the nested object. Here's my modified test code

public class Customer : IValidatableObject
{
    public Customer()
    {
        Details = new CustomerDetails();
    }

    [Required]
    [MaxLength(2)]
    public string Name
    {
        get;
        set;
    }

    public CustomerDetails Details
    {
        get;
        private set;
    }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var context = new ValidationContext(this.Details, validationContext.ServiceContainer, validationContext.Items);
        var results = new List<ValidationResult>();
        Validator.TryValidateObject(this.Details, context, results);
        return results;
    }
}

However I have problems getting all the validation errors, even when calling TryValidateObject with validateAllProperties set to true.

        var context = new ValidationContext(cs, null, null);
        var results = new List<ValidationResult>();
        Validator.TryValidateObject(cs, context, results,true);

If there are any errors in the container, only these will show. Only when there are no errors in the container object, errors in the nested object will show. I suspect it has something to do with the Validate rouine returning a full list, and not being able to add to an (existing) list from the container(?)

Are there any modifications I can make to routine to get all errors to show?

like image 958
goorj Avatar asked Dec 17 '11 22:12

goorj


Video Answer


1 Answers

See this answer: https://stackoverflow.com/a/3400627/724944

So, there is an error in your class' atributes, and therefore Validate method doesn't get called. I suggest using CustomValidationAttribute like this:

[CustomValidation(typeof(Customer), "ValidateRelatedObject")]
public CustomerDetails Details
{
    get;
    private set;
}

public static ValidationResult ValidateRelatedObject(object value, ValidationContext context)
{
    var context = new ValidationContext(value, validationContext.ServiceContainer, validationContext.Items);
    var results = new List<ValidationResult>();
    Validator.TryValidateObject(value, context, results);

    // TODO: Wrap or parse multiple ValidationResult's into one ValidationResult

    return result;

}
like image 138
surfen Avatar answered Sep 28 '22 05:09

surfen