PDA

View Full Version : ThreeState validators


CNemo7539
06-18-2007, 08:23 PM
First of all please describe what I would like to do.

I have US state dependent validation logic. It's easy to define it, but I also want to be sure that when system will get new state in the business it will not slip through the validation just because there is no rules defined.

So, I decided to use something like following:

<v:any id="PolicyValidator.State">
<v:group when="State == StateId.AZ">
<v:ref name="AZ"/>
</v:group>

<v:group when="State == StateId.OH">
<v:ref name="OH"/>
</v:group>


<v:condition id="UndefinedState.State" test="false">
<v:message id="Validation is undefined for {0}" providers="PolicyValidator">
<v:param value="State"></v:param>
</v:message>
</v:condition>
</v:any>

In the simple words if we get to the bottom of that group, that means something is wrong, and we need to fail.

And I was very disappointed to find that it's got going to work, because in "any" group "when" evaluated to false, essentially skips all processing.

Is there any way to throw message when there is no rules defined. That will be real help in production. The idea is that validator skipped is not the same as processed and returning result.

The simplest solution I see is to change code a little bit to allow validators to be in three states: true, false and disabled/skipped/whatever.
So, groups can distinguish between disabled and real outcome from Validate. I guess it will be not that difficult to implement by let say adding additional parameter to the group, something like account-when

<v:any id="..." account-when="false">...

In the DoValidate() group should check this option and process accordingly.

Because this logic is intended to make checks, might be good reason to call such groups checked.

It's just my suggestion.

PVG
07-03-2007, 02:34 PM
Hi,

You are absolutely right that a validator that was not executed (because its condition did not apply) should not simply be interpreted as true.

In fact, how a validator that is not executed must be interpreted depends upon the parent that uses this validator. In case of an AND-validator group, true is probably a good choise, but in case of an OR-validator group, a better value would be false. In this case the or validator group would fail, when no validator applies. (As I'm writing this, I'm not even sure this is what you want in most cases).

According to me, what must be added to the definition of a validator group, is a property that specifies how not applicable validators must be processed. This property can have the value of true or false.


Now coming back to your original problem. You can use a simple workaround to get exactly the behavior that you want by simply wrapping each of the "state" validator groups in an additional validator group. Let me give you an example


Code:
<v:group id="AZWrapper">
<v:ref name="AZ" when="State == StateId.AZ"/>
<v:validator test="State == StateId.AZ"/>
</v:group>

<v:group id="OHWrapper">
<v:ref name="OH" when="State == StateId.OH"/>
<v:validator test="State == StateId.OH"/>
</v:group>

<v:any id="PolicyValidator.State">
<v:group>
<v:ref name="AZWrapper"/>
</v:group>

<v:group>
<v:ref name="OHWrapper"/>
</v:group>


<v:condition id="UndefinedState.State" test="false">
<v:message id="Validation is undefined for {0}" providers="PolicyValidator">
<v:param value="State"></v:param>
</v:message>
</v:condition>
</v:any>


What you do in essence is to create a validatorgroup, (the "wrapper" validator) that contains the effective validator (the one that contains all the validators), this one is only executed when the condition is matched, and a standard validator that executes always, and tests against the value of the state property.

KR

Patrick

CNemo7539
07-03-2007, 03:32 PM
Well...

You can put "when" on group, not on the nested reference and that what I do currently.

The real need is to be able fail when nothing defined in group works. I suggested that slightly changed logic, to be able put message last in the group. Currently OR group will simply work until first when evaluates to false. That's absolutely wrong from logical point of view.

I guess it will greatly help in production, when somebody simply forget to update different parts of config. That will give us additional flexibiluty as well.