AddRule & BrokenRulesCollection - Custom Validation not working

AddRule & BrokenRulesCollection - Custom Validation not working

Old forum URL: forums.lhotka.net/forums/t/3590.aspx


dd1 posted on Tuesday, September 25, 2007

Hi all

I'm a bit of a noob with CSLA, so please bear with me if this question has been asked and answered before (I did a search but couldn't find any answers):

I've declared my rules like so:

protected override void AddBusinessRules()
{
    ValidationRules.AddRule(PhoneNumbersValid, WorkNumber");
    ValidationRules.AddRule(PhoneNumbersValid, "HomeNumber");
}

and implemented a PhoneNumbersValid like so:

private bool PhoneNumbersValid(object target, RuleArgs e)
{
    if ((_homeNumber.Value.Length > 0) || (_workNumber.Value.Length > 0))
    {
        return true;
    }
    else
    {
        e.Description = "At least one phone number must be entered and valid";
        return false;
    }
}


My problem is as follows:
When I set the HomeNumber property's value in my code, this code/rule executes. If HomeNumber's value is an empty string, the BrokenRulesCollection immediately contains a broken rule. If I then go and set the value of WorkNumber property's value to something other than an empty string, the rule again executes, but BrokenRulesCollection still contains an item which causes IsValid to be false (which is obviously not the case).

The code I've shown here is obviously vastly simplified and the actual code contains many other rules :), but I hope it brings across the problem I have.

Am I missing something or is there another way to do this? I am using the example provided in "C# 2005 Business Objects, Second Edition, Rockford Lhotka, p416" which would also seem to have the same problem.

Thanks

Dirk

skagen00 replied on Tuesday, September 25, 2007

Hey Dirk,

What is happening is that you are not re-testing the rule on the "other number" after a change is made that "validates both" by nature of one being supplied.

Override "OnPropertyChanged" of the object (be sure to call base.OnPropertyChanged). Within, if the property is WorkNumber, do ValidationRules.CheckRules("HomeNumber"). (and vice versa).

When a property gets changed normally, it only tests rules associated with the property being changed.

Below is a very simple case for me, when changing a BirthMonth may have an effect of the validity of a BirthDay.

protected override void OnPropertyChanged(string propertyName)

{

      switch (propertyName)

      {

            case "BirthMonth":

                  ValidationRules.CheckRules("BirthDay");

                  break;

            }

      base.OnPropertyChanged(propertyName);

}

Chris

 

dd1 replied on Tuesday, September 25, 2007

Thanks, Chris, implemented and it works :)

ReadOnlyChild replied on Tuesday, September 25, 2007

just for reference, version 2.1.4 has the .AddDependentProperty which will avoid overriding the PropertyHasChanged method.

This method in ValidationRules will link the two properties one way or both ways so validation on another properties are re-checked on dependent property changes.

skagen00 replied on Tuesday, September 25, 2007

Thanks, I forgot about that. (haven't retrofitted my stuff for this enhancement).

Thanks for the heads up.

dd1 replied on Wednesday, September 26, 2007

Yes, that seems to work as well and is a bit prettier.

Copyright (c) Marimer LLC