0

Validation on property of child class does not work when I have 2 different rulesets for The parent and child.

This is the class code: Mytype is the parent and Person is the child

    [HasSelfValidation]
    public class MyType
    {
        [SelfValidation(Ruleset = "RulesetA")]
        [SelfValidation(Ruleset = "RulesetB")]
        public void DoValidate(ValidationResults results)
        {
        }

        [NotNullValidator(Ruleset = "RulesetA")]
        [ObjectValidator("RulesetA", Ruleset = "RulesetA")]
        public Person Person { get; set; }

    }

    public class Person
    {
        [NotNullValidator(Ruleset = "RulesetB")]
        public string GivenName { get; set; }

    }

This is the custom validator class to validate MyType class against all rulesets:

    public interface IValidator<T>
    {
        ValidationResults Validate(T target);
    }

    public class MyValidator : IValidator<MyType>
    {
        public ValidationResults Validate(MyType target)
        {
            return Validation.Validate(target, new string[] {"RulesetA", "RulesetB"});
        }
    }

And this is the test which fails: (IsValid should be set to False but it's True)

    [TestMethod]
    public void Should_return_false_when_validating_MyType_without_PersonApplying_GivenName()
    {
        //arrange
        var myType = new MyType()
                            {
                                Person= new Person()
                            };
        myType.Person.GivenName = null;

        //act
        MyValidator _validator = new MyValidator();
        var resultList = _validator.Validate(myType);

        //assert
        Assert.IsFalse(resultList.IsValid);
    }

Would you please help?

Steven
  • 166,672
  • 24
  • 332
  • 435
mk78
  • 73
  • 1
  • 4
  • I think you should remove the `Ruleset = "RulesetA"` from the `[ObjectValidator]`. Just decorate that property with: `[ObjectValidator]`. This makes sure that the `Person` always gets validated. – Steven Oct 09 '12 at 11:13
  • no it's still failing :( – mk78 Oct 09 '12 at 11:20
  • And when you add `[ObjectValidator("RulesetB", Ruleset = "RulesetB")]` (and `RulesetA`) to the `Person` property? – Steven Oct 09 '12 at 11:24
  • It works but my question is that why it's not working in my case even though I am validating against all rulesets: Validation.Validate(target, new string[] {"RulesetA", "RulesetB"}); – mk78 Oct 09 '12 at 11:31

1 Answers1

1

VAB validates your object per ruleset and concatenates the validation results. This is what the Validation.Validate method looks like:

var resultsReturned = new ValidationResults();

foreach (string ruleset in rulesets)
{
    var validator = ValidationFactory.CreateValidator(
        targetType, ruleset, source);

    foreach (var validationResult in validator.Validate(target))
    {
        resultsReturned.AddResult(validationResult);
    }
}

return resultsReturned;

In other words, a validation on an object is always performed on a single ruleset. Since the ObjectValidator is only decorated for RulesetA, the Person object will not get validated when running on RulesetB.

Steven
  • 166,672
  • 24
  • 332
  • 435