After some tedious debugging, I seem to have come up with a combination of factors that throws a nasty exception. I am wondering if this is a bug in the Csla framework (v2.1 release). At a minimum, I would like to post this to save someone some time (as this forum has saved for me many times).
In my project, I have a class that inherits from ReadOnlyBase, and each of the property accessors feature the 'CanReadProperty()' call to protect from unauthorized access.
The code works fine when I run it locally; but when I deploy it to my remote WEB (IIS) server, and run it under 'click-once' deployment on a separate test box, I get a 'NullReferenceException'. The error message includes reference to the CanReadProperty call. If I comment out the CanReadProperty() call and redeploy to the web server, everything works great.
Here are some other pertinent facts:
There are no authorization rules implemented yet, so the calls should just return without any exception. The code I am deploying is compiled in debug mode. My CanReadProperty calls utilize the explicit property name, eg: CanReadProperty("PropertyName", true);. (to defend against the reflection bug reported elsewhere).
Here is the offending code:
[Serializable()]
public class LoginSettings : Csla.ReadOnlyBase<LoginSettings>
{
#region Business Properties and Methods
int _employeeID=0;
public int EmployeeID
{
get
{
CanReadProperty("EmployeeID", true); //comment this out if you want it to work
return _employeeID;
}
}
...
Good suggestion, I'll try it this weekend.
The problem presented itself on a non-development test box, while testing click-once deployment of a Windows Forms app off of a web server. Crude troubleshooting was involved. Nontheless, the problem was very repeatable.
Did anyone investigate this further?
I get the exact same behaviour on my ReadOnly BO objects and I spent a few hours debugging before I narrowed it down to the CanReadProperty method in ReadOnlyBase. My current workaround is to override CanReadProperty in my BO and always return true (which will be OK for the time beeing).
Yes, I'm running the C#-version of CSLA.NET 2.1. I followed your advice from the other thread (titled: application hang when using remote ws-portal) and I get similar problem when I try to access a property in a clone of a very simple (no complex object graph) ReadOnlyBase-derived object.
1. Create a ReadOnlyBase-derived object (using the latest C#-codesmith templates)
2. Create a list of the same ReadOnly object
3. Reproduce using local portal (Or use remote portal without the need to clone)
MyReadOnlyObjectList list = MyReadOnlyObjectList.GetMyReadOnlyObjects();
//assume list.count > 0
MyObject a = list[0];
MyObject b = a.Clone();
Mbox("Yes, I can read this property: " + a.MyProperty);
Mbox("No, I can't read this property: " + b.MyProperty);
In the last case (reading from b) a NullReferenceException is thrown somewhere within the CanReadProperty(true) in ReadOnlyBase
Notice: I haven't added any authorization-rules to the object. Perhaps the current templates C#-templates for CodeSmith lacks some calls to init-method in the derived BO constructors ? I am aware that the templates aren't part of the CSLA framework, but the behaviour I'm seeing here must be something within CSLA?
I have a feeling the error must be on my part, as this (ReadOnlyBase) presumably is an frequently used feature of the framework and more people would have reported this as a bug earlier ?
Hi,
We have the same problem with readonly object in remoting.
I look at the CSLA code and I saw that _authorizationRules is not serializable.
I can't see where this field is reinitialized after deserialization.
The property is readonly so we can't reinitialize the field after deserialization.
Is there something I don't understand?
Alain
the _authorizationRules field is never used directly - only through the AuthorizationRules property, which does re-instantiate the object
protected Security.AuthorizationRules AuthorizationRules
{
get
{
if (_authorizationRules == null)
_authorizationRules = new Security.AuthorizationRules(this.GetType());
return _authorizationRules;
}
}
This automatically reestablishes the connection to any per-type rules, and is triggered during the deserialization process by the code in OnDeserializedHandler(), which also causes your code to add any per-instance rules.
I would suggest going to the click once deployment folder, run the exe from there and attach VS to that process so you can debug the project right there and be able to step through the code and see exactly where the problem happens (in case you haven’t don’t it already).
It’s really easy to do:
Hopefully this will shade some light on the cause of the problem.
Copyright (c) Marimer LLC