Csla.PropertyLoadException System.InvalidCastException when trying SetProperty

Csla.PropertyLoadException System.InvalidCastException when trying SetProperty

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


xAvailx posted on Wednesday, April 01, 2009

CSLA 3.6.1

Hi, I have a class that has a child property. The child property is of a base type for which other classes inherit. For example:

Product.SubType

SubType is of type SubTypeBase

Then I have CarSubType, TruckSubType which inherit from SubTypeBase.

When I try to use SetProperty I get the following exception:


Csla.PropertyLoadException: Property load or set failed for property Child (Object must implement IConvertible.) ---> System.InvalidCastException: Object must implement IConvertible.
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType)
at Csla.Utilities.CoerceValue(Type desiredType, Type valueType, Object oldValue, Object value) in D:\Projects\CSLA\C#\cslacs-3.6.1-090204.zip\cslacs\Csla\Utilities.cs:line 199
at Csla.Core.FieldManager.FieldDataManager.SetFieldData(IPropertyInfo prop, Object value) in D:\Projects\CSLA\C#\cslacs-3.6.1-090204.zip\cslacs\Csla\Core\FieldManager\FieldDataManager.cs:line 203
at Csla.Core.BusinessBase.SetProperty(IPropertyInfo propertyInfo, Object newValue) in D:\Projects\CSLA\C#\cslacs-3.6.1-090204.zip\cslacs\Csla\Core\BusinessBase.cs:line 2383
--- End of inner exception stack trace ---
at Csla.Core.BusinessBase.SetProperty(IPropertyInfo propertyInfo, Object newValue) in D:\Projects\CSLA\C#\cslacs-3.6.1-090204.zip\cslacs\Csla\Core\BusinessBase.cs:line 2393
at etc...

Is this scenario not supported?

Any help is appreciated. Thx.


EDIT:

If I implement IConvertible on the child types, then it appears to work. However I am wondering if this shouldn't be handled by the framework? All I am doing is implementing ToType and casting as the base class.

EDIT2:

After some more digging, I am wondering if this check in CoerceValue should be different:

if (desiredType.Equals(valueType))
{
// types match, just return value
return value;
}

RockfordLhotka replied on Wednesday, April 01, 2009

How do you propose changing the code in CoerceValue()?

xAvailx replied on Wednesday, April 01, 2009

Instead of using Equals, can it just check if it is of the same type?

if (desiredType is valueType))
{
// types match, just return value
return value;
}

I think that would work, I can modify my source see what happens...

RockfordLhotka replied on Wednesday, April 01, 2009

I don't think the 'is' operator works that way.

It is used to compare an instance to a type

if (_customer is Customer)

but 'desiredType' is a Type object, and so it would never be of type
'valueType'.

Rocky

xAvailx replied on Thursday, April 02, 2009

Hi, Rocky:

This should work:

var t = a.GetType();
var u = b.GetType();

if (t.IsAssignableFrom(u) || u.IsAssignableFrom(t)) {
// x.IsAssignableFrom(y) returns true if:
// (1) x and y are the same type
// (2) x and y are in the same inheritance hierarchy
// (3) y is implemented by x
// (4) y is a generic type parameter and one of its constraints is x
}

or this:

private bool AreSame(Type a, Type b)
{
if(a == b) return true; // Either both are null or they are the same type

if(a == null || b == null) return false;

if(a.IsSubclassOf(b) || b.IsSubclassOf(a)) return true; // One inherits from the other

return a.BaseType == b.BaseType; // They have the same immediate parent
}

These are the responses I got in StackOverflow. Here is the thread if you are interested
http://stackoverflow.com/questions/708205/c-object-type-comparison

I will give it a try on my project and run the csla unit tests.

xAvailx replied on Friday, April 03, 2009

FYI, I ran the tests in Cslacs.Test/PropertyGetSet, all 28 tests passed.

All I changed was to this:

if (desiredType.IsAssignableFrom(valueType))
{
// types match, just return value
return value;
}

It was enough to fix this scenario and avoid implementing IConvertible.

Thx.

RockfordLhotka replied on Thursday, April 23, 2009

I've checked this fix into svn, so it will be included in the 3.6.3 builds
going forward.

Thanks,

Rocky


-----Original Message-----
From: xAvailx [mailto:cslanet@lhotka.net]
Sent: Friday, April 03, 2009 6:24 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Csla.PropertyLoadException
System.InvalidCastException when trying SetProperty

FYI, I ran the tests in Cslacs.Test/PropertyGetSet, all 28 tests passed.

All I changed was this:

if (desiredType.IsAssignableFrom(valueType))
{
// types match, just return value
return value;
}

It was enough to fix this scenario and avoid implementing IConvertible.

Thx.

asp2go replied on Saturday, October 24, 2009

I am still receiving this error under the same scenario, is there anything else to check (using 3.7.1) :

[InvalidCastException: Object must implement IConvertible.]
   System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) +7596825
   System.Convert.ChangeType(Object value, Type conversionType) +32
   Csla.Utilities.CoerceValue(Type desiredType, Type valueType, Object oldValue, Object value) +766
   Csla.Core.FieldManager.FieldDataManager.LoadFieldData(IPropertyInfo prop, Object value) +62
   Csla.Core.BusinessBase.LoadProperty(IPropertyInfo propertyInfo, Object newValue) +42

stefan replied on Thursday, April 02, 2009

Hi,

I don't know if the following is even impossible by definition, but
I went even further and tried it with interfaces, like:

Private Shared myProperty As PropertyInfo(Of ISomeInterface) = _
    RegisterProperty(Of ISomeInterface)(GetType(MyType), New PropertyInfo(Of ISomeInterface ("MyProp"))

But I got the same exception as you.

Wouldn't

if (typeof(ISomeInterface).IsAssignableFrom(myType)) { ... }


help in CoerceValue?

Stefan

RockfordLhotka replied on Saturday, October 24, 2009

Please provide an example showing the failure. This thread was 6 months ago, and I have no memory of what was or wasn't done at that time.

Copyright (c) Marimer LLC