Potential Bug / Issue - DenyRead Conflict with ComboBox

Potential Bug / Issue - DenyRead Conflict with ComboBox

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


NeilMicklethwaite posted on Friday, March 23, 2007

Hi

I have come across a problem which is a potential bug / issue in CSLA 2.1.1.4 whilst trying to DenyRead on a value displayed in a ComboBox and wanted to flag it up.

This is all in VB.Net.

I have my object (Person) binding source and a name value List (GeographicalArea) binding source set up and form utilising data binding and the tools provided within CSLA.

My person object has GeographicalAreaID as a property

My combo box is set to display a value from the Geographical Area Name value list as follows.

ComboBox.DataSource = BindingSourceGeographicalAreaList

ComboBox.DisplayMember = Value

ComboBox.ValueMember = Key

ComboBox.SelectedValue =  BindingSourcePerson - GeographicalAreaID

I want to DenyRead on certain roles and have set up the Authorisation Rule as follows:-

AuthorizationRules.DenyRead("GeographicalAreaID", "CVS Admin")

I have a CSLA.Windows.ReadWriteAuthorization and CSLA.Windows.BindingSourceRefresh on the form linked to the Person Binding Source as required

The Geographical Area Combo Box is set to Apply Authorisation on the ReadWriteAuthorisation

When I Access the form as a user in the Role 'CVS Admin' - I get an exception whilst internally trying to set the SelectedValue on the ComboBox.

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentNullException: Value cannot be null.

Parameter name: key

at System.Windows.Forms.CurrencyManager.Find(PropertyDescriptor property, Object key, Boolean keepIndex)

at System.Windows.Forms.ListControl.set_SelectedValue(Object value)

--- End of inner exception stack trace ---

I traced it to the ApplyReadRules Routine in ReadWriteAuthorization.vb at the point when the control is disabled and the code tries to SetValue on the PropertyInfo.

If propertyInfo IsNot Nothing Then

propertyInfo.SetValue(ctl, _

GetEmptyValue( _

Utilities.GetPropertyType(propertyInfo.PropertyType)), _

New Object() {})

End If

I have basically put in a temporary fix as follows: -

If propertyInfo IsNot Nothing Then

If TypeOf (ctl) Is ComboBox Then

propertyInfo.SetValue(ctl, String.Empty, New Object() {})

Else

propertyInfo.SetValue(ctl, _

GetEmptyValue( _

Utilities.GetPropertyType(propertyInfo.PropertyType)), _

New Object() {})

End If

End If

This gets me around the issue but maybe not in the neatest way possible. Incidentallly I tried the original code using Infragistics ultra combo box which allows null values and it worked just fine.

 

stefan replied on Tuesday, November 27, 2007

Hi @all,

I have run into exacly the same issue, and I think that it is not an uncommon scenario.

Have others handled it the same way as in the first post,
or is there an implementation mistake on my side?

Rocky, have you seen this?

Stefan


stefan replied on Friday, May 09, 2008

Bumping this one up again.

This still IS an issue, even with .NET 3.5/CSLA 3.5,
resulting from ReadWriteAuthorization.cs:

    private void ApplyReadRules(
      Control ctl, Binding binding,
      bool canRead)
    {
        // ...

        // clear the value displayed by the control
        PropertyInfo propertyInfo =
          ctl.GetType().GetProperty(binding.PropertyName,
          BindingFlags.FlattenHierarchy |
          BindingFlags.Instance |
          BindingFlags.Public);
        if (propertyInfo != null)
        {
          propertyInfo.SetValue(ctl,
            GetEmptyValue(
              Utilities.GetPropertyType(
                propertyInfo.PropertyType)),
              new object[] { });
        }

        // ...
    }

Comboboxes don't like GetEmptyValue returning "Nothing".

What do you think about the solution presented in the first post?


Stefan

ajj3085 replied on Friday, May 09, 2008

What exactly is the problem?  What do your property getter look like?  What is your combobox setup like (allow the user to type text, or only pick from the list)?

I did a test application, I don't get any exceptions and the combobox is disabled properly.

Your property getter should look like this:
public string MyString {
    get {
       string result;

       if ( CanReadProperty( "MyString" ) ) {
          result = myString;
       }
       else {
          result = "";
       }

       return result;
    }
    set { // your set code here }
}

Andy

stefan replied on Friday, May 09, 2008

Well Andy,

following the example from the OP, modify your test app so that your property
returns an integer foreign key. Then bind a combobox to this property (without any extra work)
...and see what happens when CanReadProperty returns false...


Stefan

ajj3085 replied on Friday, May 09, 2008

Ahh, I see why I never had this problem before.  Change the BO so that your client UI should be setting text.  The BO will internally use the NVL to translate the text value to the key value.  One of your validation rules should ensure that the text value does in fact map back to a key value.

Something else that may or may not work would be to modify the Binding in the Designer.cs file so that the "nullValue" parameter is -1 or something.  Then RWAuth should be modified to return DBNull.Value instead of null in GetEmptyValue.  I have no idea if it would work though, but it does seem from the documentation that ComboBox expectd DBNull.Value and can deal with it, but it doesn't know  how to handle null (Nothing in Vb.Net).

I know the first solution works, because I actually setup my BOs to work like this.  The nice thing is that I can change the key of the NVL if I ever chagne the key in the database... I like to design BOs so that the client never needs to know the database id of the BO, ever.

stefan replied on Tuesday, December 18, 2007

Bumping this one up again!

Is there a better solution to this than the fix described?

Stefan


ajj3085 replied on Tuesday, December 18, 2007

NeilMicklethwaite:
I have come across a problem which is a potential bug / issue in CSLA 2.1.1.4 whilst trying to DenyRead on a value displayed in a ComboBox and wanted to flag it up.


Well, the 2.x branch is basically defunct now.  I would try upgrading to 3.0.3 if possible.  See this for more information.

Copyright (c) Marimer LLC