Vibrant discussion about CSLA .NET and using the framework to build great business applications.
Hello all. I'm using Authorization Rules in my Business Objects but when any Authorization Rule is broken the message provided on the exception do not fits my needs. I was reviewing the implementation of the DataPortal class and CSLA throws a Security Exception and loads the exception message from a resource. I really wanted to know if there's a way to change that message to a customized dynamically created message without modify my DataPortal class, I also can't write directly in the resource file because the message is not always the same.
As far as I know: no. The EditObject action would be possible by overriding BusinessBase Save() Method or somthing in this area.
If I got the idea from the ebook ("Creating Business Objects") right, receiving a Security Exception for a broken authorization rule should be an "exception".
It's the UI's responsibility to check if its allowed before doing it:
Also have a look at Csla.Xaml.ViewModelBase, which provides the Can.... Properties.
Here's a post which suggests to use validation rules in some cases rather than authorization rules. http://forums.lhotka.net/forums/p/5760/28042.aspx
CSLA does not provide a direct method for replacing the error message with your own.But you can add the checks in your own code and throw your own exception.
For the DataPortal you will have to implement the authorization check in you own static factory methods, ex:
public static Root NewEditableRoot()
if (!Csla.Rules.BusinessRules.HasPermission(AuthorizationActions.CreateObject, typeof(Root)))
throw new SecurityException("my custom message");
For Save I would recommend that you create your own intermediate base class for ex BusinessBase and override the Save method and you could even promote the message to a property or lambda expression (marked as nonserializable) to allow to just set the message for each object.
public class MyBusinessBase<T> : Csla.BusinessBase<T> where T:MyBusinessBase<T>
public override T Save()
throw new InvalidOperationException(Csla.Properties.Resources.NoSaveChildException);
if (EditLevel > 0)
throw new InvalidOperationException(Csla.Properties.Resources.NoSaveEditingException);
if (!IsValid && !IsDeleted)
throw new Csla.Rules.ValidationException(Csla.Properties.Resources.NoSaveInvalidException);
throw new InvalidOperationException(Csla.Properties.Resources.BusyObjectsMayNotBeSaved);
// this is the same check that DataPortal does for object of type BusinessBase
if (!Csla.Rules.BusinessRules.HasPermission(Csla.Rules.AuthorizationActions.DeleteObject, this))
throw new System.Security.SecurityException("custom message - not allowed to delete");
if (!Csla.Rules.BusinessRules.HasPermission(Csla.Rules.AuthorizationActions.EditObject, this))
throw new System.Security.SecurityException("custom message - not allowed to save");
result = (T) DataPortal.Update(this);
result = (T)this;
OnSaved(result, null, null);
Jonny Bekkum, Norway
good, clean sample of what I meant to say....
Thats works for me. Thanks a lot guys.