Updating AddAuthorizationRules result in Csla.Validation.ValidationException in version 2.1.4

Updating AddAuthorizationRules result in Csla.Validation.ValidationException in version 2.1.4

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


jason2000 posted on Monday, July 02, 2007

1 .I updated AddAuthorizationRules() in Project like this

    protected override void AddAuthorizationRules()
    {
      AuthorizationRules.AllowWrite("Name", "Administrator");
      AuthorizationRules.AllowRead("Name", "Administrator");
      AuthorizationRules.AllowWrite("Started", "ProjectManager");
      AuthorizationRules.AllowWrite("Ended", "ProjectManager");
      AuthorizationRules.AllowWrite("Description", "ProjectManager");
    }

2.Log in as rocky/lhotka

3.select a project and Edit it

4.log out

5.log in as pm/pm

6.update the current project and Save

7.Csla.Validation.ValidationException:Object is still being edited and can not be saved

RockfordLhotka replied on Monday, July 02, 2007

In general, if you are going to deny read to some roles then you need to alter the way you implement property get blocks, so they return a dummy value rather than throwing an exception:

Public Property Name() As String
  Get
    If CanReadProperty() Then
      Return mName
    Else
      Return String.Empty
    End If
  End Get
  ' ...

The reason this is required is due to the way data binding works (in Windows Forms and WPF anyway). Even though the AuthorizeReadWrite control in Windows Forms blocks display of the value, there's no way to prevent data binding from reading the property, and of course triggering the exception...

The same is true with the Authorizer control in WPF. It blocks the display, but can't stop data binding from reading the property.

It is also possible that there are ways to improve the edit forms in PTWin. In PTWpf, for example, I specifically cancel all edits when the user's identity changes, and that would probably be a good idea in PTWin as well. That avoids any oddities around partially-edited-but-now-not-editable properties or things of that nature.

jason2000 replied on Tuesday, July 03, 2007

Rocky,Thank you for your immediate response .

snesbitt replied on Monday, August 06, 2007

The technique that Rocky mentioned above is also necessary if the property has ValidationRules, such as MaxStringLength.  If a user is not authorized to read a particular property, but the property has a ValidationRule, the object would always throw an exception when a new instance is created via the factory method because the validation rule would attempt to read the property.

I first tried to avoid this error from being thrown by wrapping a conditional statement around the ValidationRule in the AddBusinessRules method:

protected override void AddBusinessRules()

{

   if ( CanReadProperty("SomeProperty") && CanWriteProperty("SomeProperty") )

  {

    ValidationRules.AddRule( ... );

  }

}

 

This resulted in a pretty serious issue.  Without going into painful detail, the Csla.Core.BusinessBase private constructor processes the ValidationRules before the AuthorizationRule.  However if you call the CanReadProperty method before the AuthorizationRules are processed, then the AuthorizationRules dictionary is initialized prematurely, without regard to the BO rules or user's roles.  By the time the AuthorizationRules are processed by the base constructor, the AuthorizationRules dictionary already exists, so the constructor never calls the BO's override AddAuthorizationRules.  This results in the properties being available for read and write even if the current user does not have the appropriate roles.

I do not regard this is a bug - I simply mention it because it caught me out and took me almost an hour to track down.  So hopefully this will help someone else avoid this side-effect.

Copyright (c) Marimer LLC