How to trigger validation rules between child objects.

How to trigger validation rules between child objects.

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


stuart.bale posted on Monday, July 22, 2013

What would you do in this situation?

Parent A

 Child B

  Property B1

 Child C

  Property C2

Basically, there is a parent business object, with two child business objects, each with a property.

Now, what I need is to have a validation rule on Child B Property B1, that checks if the value in Child C Property C2 is the same.  

So this would need to be triggered whenever either Child B Property B1 changes, or Child C Property C2 changes.

I don't want Child B to have to know about the existence of Child C, or vice-versa.

This is a cut down example of a real-world issue, which is far more complex, but finding a simple approach to this should apply for the more complex.

BTW, it's impractical for me to have a replica of Child B Property B1 and/or Child C Property C2 on Parent A.

And I am quite ok to use multiple rules, and to trigger them from OnChildChanged, if that makes it easier.

I'm using CSLA 4.3.

I'm open to any suggestions.

cfarren replied on Monday, July 22, 2013

I think the best way to handle this would be to have a rule in ParentA that looks at both Child B and C whenever the child object is changed.

In Parent A you will obviously need a property that is of type ChildA and one of type ChildB. Create a rule for each of these properties that checks whatever fields you need in the Child objects.

then override the OnChildChanged method.

protected override void OnChildChanged(Csla.Core.ChildChangedEventArgs e)

{

   base.OnChildChanged(e);

   if (e.ChildObject is ChildA && e.PropertyChangedArgs.PropertyName.Equals("PropertyB1"))

      PropertyHasChanged(_ChildAProperty);

   }

}

This should fire the rule you created for ChildA property.
Is this what you're after?

JonnyBee replied on Tuesday, July 23, 2013

Hi,

The rule must be registered on the object that should have the broken rule message.

And if the child A and child B is not allowed to know about each other youn will have to add some logic to the list (assuming rules are connected to the child objects) and trigger som special rule on all objects - and the rule in each child must must be able to call a  method on the list (Parent) for existance of other values in list. You _MAY_ use an objectlevel rule to control when this rule is executed by your code (f.ex OnChildChanged in the list).

stuart.bale replied on Friday, July 26, 2013

Hi Jonny,

Just to clarify, in this case, Parent ISN'T a BusinessListBase, it is just BusinessBase.

So I think, what you'd recommend is that the child object calls a method on it's Parent property, as part of the business rule attached to the property on the child.

So, for example, we could add a rule PropertyB1IsValid, and Add it to Child B, using the PropertyB1 property as a param.

Then, inside that rule, we would get the Parent of the Target, and call a method, such as GetChildCPropertyC2(), which returns the value of Property C2 on Child C.  We can then compare the values, and set the appropriate rule result.

The only downside of this, is that the validation would only appear on PropertyB1 of Child B - whereas I actually want it to appear on both the properties.

I guess I could capture the OnChildChanged event on the Parent (as cfarren suggests), but then how do I call each child to tell it to only run the rules attached to one specific property?

 

JonnyBee replied on Friday, July 26, 2013

I see this as multiple steps. 

  1. Validate the field that has been editet - and within the Execute method get the Parent and cast to some interface and get some additional value as input for validation. This will put the validation error on ChildB
  2. Then Parent must have code in OnChildChanged to trigger validation on ChildC as these 2 objects do not know about each other. On an object that is databound you should call the PropertyHasChanged method in ChildC. You may have to add a new interface and method to your child objects in order to do that. PropertyHasChanged will run business rules for the given property (and affected properties) and call OnPropertyChanged to notify UI of changes to field/brokenrules. 

Copyright (c) Marimer LLC