[csla 3.8.4] WPF-Textbox Visibility bound to PropertyStatus.CanRead -> Breaks Required validation rule!

[csla 3.8.4] WPF-Textbox Visibility bound to PropertyStatus.CanRead -> Breaks Required validation rule!

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


stefan posted on Wednesday, May 04, 2011

I have a WPF Textbox with its Visibility bound to the CanRead property of a Csla.Wpf.PropertyStatus control.

The Text is bound to a string property of my business object which is decorated with the Required attribute from the System.ComponentModel.DataAnnotations namespace.

When CanRead evaluates to false, the Textbox is hidden, but the PropertyStatus control shows up with the Required rule being broken...

It seems that the PropertyStatus control does not interact with the BO property values directly, but only have access to what is visible...

Is that right the expected behavior or am I doing something wrong?

Here is my Xaml:

                <TextBox Text="{Binding Path=Model.Nr, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Visibility="{Binding ElementName=propStatusNr, Path=CanRead, Converter={StaticResource VisibilityConverter}}" />

                <cslaxaml:PropertyStatus Name="propStatusNr" Width="20" Height="20" Property="{Binding Path=Model.Nr}" />

 

RockfordLhotka replied on Wednesday, May 04, 2011

Your problem is that you want the PropertyStatus to disappear too?

Just bind its Visibility to CanRead, like you do for the TextBox. Or put the TextBox and PropertyStatus in a container (Grid, StackPanel, etc) and bind the container's Visibility to hide both controls at once.

stefan replied on Wednesday, May 04, 2011

The problem I see, is that, although one property is hidden, the object is still valid...

Or does the red Error icon from PropertyStatus not represent a "real" broken rule?

RockfordLhotka replied on Wednesday, May 04, 2011

The rule will run irregardless of whether the user is authorized to see the value. Validation and authorization rules are independent from each other.

You can use rule short-circuiting to create a rule for that property that prevents other rules from running if the user isn't authorized. Add that rule at priority -1, and it should prevent CSLA from running even the DataAnnotations rules.

stefan replied on Thursday, May 05, 2011

I finally found the issue. It is an old one that I often struggled with:

The DataAnnotation rule accesses the object's properties just like any user would. So if CanReadProperty returns false, the rule just sees a default value (""|0|NULL).

This somehow contradicts:

RockfordLhotka

The rule will run irregardless of whether the user is authorized to see the value. Validation and authorization rules are independent from each other.

It is like the users authorization also authorizes the rule subsystem's access to the objects. Not quite independent, as it seems to me.

So I am left to write my own StringRequired rule for each type, as the rules in the Csla.Validation namespace don't use BypassPropertyChecks either. (Or did that somehow change in current versions?)

 

RockfordLhotka replied on Thursday, May 05, 2011

DataAnnotations attributes are a hybrid scenario, and how they work depends on the UI technology being used.

In ASP.NET MVC or the Silverlight DataForm control, the UI directly invokes the attributes, and there's nothing you or I can do about that.

In all cases, CSLA adds the attributes as priority 0 rules - that's true in CSLA 3.8 and 4.

So if you prevent CSLA from running priority 0 rules,  such as by having an explicit StopProcessing rule at priority -1, you can prevent CSLA from running the attributes (and all other priority 0+ rules).

But you can't stop the UI technology from invoking the attribute - that's built into the UI platforms themselves.

stefan replied on Friday, May 06, 2011

OK!

And what about the built-in csla rules using something like BypassPropertyChecks when accessing property getters?

And does CSLA 4 differ from 3.8  regarding that aspect?

RockfordLhotka replied on Friday, May 06, 2011

Business and validation rules are never run through a property getter. Only authorization rules run in a getter, and they are blocked by BypassPropertyChecks.

The rule is running during a property set operation, or in a explicit CheckRules call (perhaps as the object is created).

Did you put a short circuit rule in at priority -1 to block rules from running? If so, what does that rule look like?

stefan replied on Friday, May 06, 2011

Sorry if I did not point out clearly what I wanted to know. Mentioning the DataAnnotations obviously misled you...

My question targets the standard CSLA (built-in) rules like the StringRequired rule. This rule, as any other rule, needs to check the related property value.

In the past, it did that by invoking the getter using reflection, and it did hit the authorization rules, because there was no BypassPropertyChecks.

Is this still the case in CSLA 3.8.x and CSLA 4?

RockfordLhotka replied on Friday, May 06, 2011

Business and validation rules have never run from a getter. Only authorization rules. And they are suppressed with BypassPropertyChecks.

Business, validation, and authorization rules run from a setter. They are all suppressed with BypassPropertyChecks.

Inside a rule, the rule's implementation may interact with properties on the object. In that case, to avoid authorization rules from running in the getter, the rule must do one of:

 

stefan replied on Friday, May 06, 2011

So then again, here comes my question unchanged: Crying

How do the built-in validation rules (e.g. StringRequired) handle this issue in 3.8.4 vs. 4?

P.S.: In any of my posts did I say that rules were called from a getter, but the rules themselves call the getter to do their work.

 

 

RockfordLhotka replied on Friday, May 06, 2011

Sorry, I assumed you'd looked at the code, and were asking a more complex question.

http://www.lhotka.net/cslacvs/viewvc.cgi/core/branches/V3-8-x/cslacs/Csla/Validation/CommonRules.cs?view=markup

The 3.x CommonRules use reflection to invoke the getter, so authorization rules apply.

In CSLA 4 the rules use the new InputPropertyValues feature, and so get the property values in a way that bypasses authorization rules.

stefan replied on Friday, May 06, 2011

Shame on me - I really should have looked at the code - Should have been a one-line-answer...Embarrassed

Copyright (c) Marimer LLC