TypeCastException when trying to update entity

TypeCastException when trying to update entity

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


WMeints posted on Sunday, May 11, 2008

When I try to update an entity I get a type-cast error:

System.InvalidCastException: Cannot convert object of type System.Collections.Generic.Dictionary`2[System.String,System.Boolean] to System.String

Stacktrace:

System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteString(NameInfo memberNameInfo, NameInfo typeNameInfo, Object stringObject)
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteKnownValueClass(NameInfo memberNameInfo, NameInfo typeNameInfo, Object data)
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMembers(NameInfo memberNameInfo, NameInfo memberTypeNameInfo, Object memberData, WriteObjectInfo objectInfo, NameInfo typeNameInfo, WriteObjectInfo memberObjectInfo)
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMemberSetup(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo, String memberName, Type memberType, Object memberData, WriteObjectInfo memberObjectInfo)
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo, String[] memberNames, Type[] memberTypes, Object[] memberData, WriteObjectInfo[] memberObjectInfos)
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
Csla.Serialization.BinaryFormatterWrapper.Serialize(Stream serializationStream, Object graph) in D:\CSLA\cslavb\Csla\Serialization\BinaryFormatterWrapper.vb: line 42
Csla.Core.ObjectCloner.Clone(Object obj) in D:\CSLA\cslavb\Csla\Core\ObjectCloner.vb: line 32
Csla.Core.BusinessBase.GetClone() in D:\CSLA\cslavb\Csla\Core\BusinessBase.vb: line 1107
Csla.Core.BusinessBase.Clone() in D:\CSLA\cslavb\Csla\Core\BusinessBase.vb: line 1094
Csla.DataPortal.Update(Object obj) in D:\CSLA\cslavb\Csla\DataPortal\Client\DataPortal.vb: line 419
Csla.DataPortal.Update[T](T obj) in D:\CSLA\cslavb\Csla\DataPortal\Client\DataPortal.vb: line 310
Save() in D:\CSLA\cslavb\Csla\BusinessBase.vb: line 125
Finance247.Library.Tests.AccountTest.TestAddMutation() in C:\Projects\Finance247\Finance247.Library.Tests\AccountTest.vb: line 112


As far as I know the object in question should update itself correctly and I'm not sure why this happens. The code to update the parent object is as follows:

    Protected Overrides Sub DataPortal_Update()
        Dim data As New AccountData

        data.Id = ReadProperty(Of Long)(IdProperty)
        data.Name = ReadProperty(Of String)(NameProperty)
        data.Balance = ReadProperty(Of Decimal)(BalanceProperty)

        data = DataProvider.UpdateAccount(data)
        LoadObjectData(data)

        DataPortal.UpdateChild(ReadProperty(Of MutationCollection)(MutationsProperty), Me)
    End Sub


The child is a collection of mutation objects.
I hope someone can help me solve this problem.

RockfordLhotka replied on Monday, May 12, 2008

The problem isn't in your DP_Update() code - the exception occurs in DataPortal.Update() when it calls Clone() to get a copy of your object (read the stack trace from bottom up and you'll see what I mean).

So the .NET serializer is unable to serialize your object for some reason - and that can be a tough issue to debug, because it means you have some field declared that the BinaryFormatter is unable to figure out...

You can create a simple test that creates an instance of your object and then calls Clone() on it - that should fail too. Then you can work on figuring out what field (or property value?) is causing the failure.

WMeints replied on Monday, May 12, 2008

Thanks for the reply. I've created a new testcase for each of the entities to check the clone functionality. All my entities pass this test, however the testcase that I created earlier to check if an account could be saved including the mutations done on the account fails.

I did however find something that striked me as odd. The offending field is a dictionary(Of String,Of Boolean) and there isn't one in my code. There is one however in BusinessBase:

[NonSerialized, NotUndoable]
private
Dictionary<string, bool> _executeResultCache;

Reflector tells me that it should not be serialized. It could well be that I need to try to recompile CSLA from source and check the results using PEVerifier.

WMeints replied on Monday, May 12, 2008

Okay .. *grabs his windows DVD* Time to reinstall this machine, now I get other weird errors too. Looks like Windows is messed up, my code is fine and runs okay on another machine.

Thanks for the help, at least it showed me where to check if something like this fails.

Copyright (c) Marimer LLC