I'm trying to add a property to a BLB-derived class that is of type BO. When doing so, I get a serialization error on load. Here is the code:
Private _Note As Note.Note = New Note.Note Public ReadOnly Property Note() As Note.Note Get Return _Note End Get End Property Protected Overrides Sub OnGetState(ByVal info As Csla.Serialization.Mobile.SerializationInfo) MyBase.OnGetState(info)
info.AddValue(
"_Note", _Note) End Sub Protected Overrides Sub OnSetState(ByVal info As Csla.Serialization.Mobile.SerializationInfo) MyBase.OnSetState(info)_Note =
CType(info.Values("_Note").Value, Note.Note) End Sub
And the error when loading:
Type 'Business.BusinessClasses.Note.Note' with data contract name 'Note:http://schemas.datacontract.org/2004/07/Business.BusinessClasses.Note' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
Is there something wrong with this approach? I haven't tried adding a child property like this to a BLB before. Am I missing something? Thanks
The MobileFormatter (which uses the DataContractSerializer behind the scenes) only works with types that implement IMobileObject. If your Note type doesn't implement that interface (which is best done by inheriting from one of the CSLA base classes, or at least MobileObject) then it can't be serialized.
An alternative, if you absolutely can't make Note implement the right interface, is for you to manually convert the state of Note into a byte stream (string, byte[], XML string, etc) and put that into the SerializationInfo object.
Based on what you said, it sounds like this should be working. The Note object is a standard CSLA BO. I even tried creating a simple class that implements IMobileObject and uses private backing fields (a la this thread http://forums.lhotka.net/forums/thread/31394.aspx) but no luck.
I'm wondering if my problem is that I'm putting my property on a BLB object? Is this supported?
I've changed my approach in the meantime from using a Note object to using a bunch of primitive type properties. Ideally I would like to get it working with the Note object...
Ahh, it occurs to me that you need to add the Note object as a child,
not as a field.
You are overriding OnSetState(), etc. There’s a separate pair
of methods to get/set child object references in the serialization stream,
because more work is done for a child object reference than for a field.
I don’t remember if BLB allows you to override the get/set
child methods though, because it obviously uses them to get/set the contents of
the collection itself. But you should check and see if they are available for
override (just make sure to call the base implementations or you’ll lose
the contents of the collection!).
Rocky
From: pondosinat
[mailto:cslanet@lhotka.net]
Sent: Friday, July 17, 2009 10:20 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Serialization Error on BusinessListBase
Based on what you said, it sounds like this should be working. The Note
object is a standard CSLA BO. I even tried creating a simple class that
implements IMobileObject and uses private backing fields (a la this thread http://forums.lhotka.net/forums/thread/31394.aspx)
but no luck.
I'm wondering if my problem is that I'm putting my property on a BLB
object? Is this supported?
I've changed my approach in the meantime from using a Note object to using a
bunch of primitive type properties. Ideally I would like to get it working with
the Note object...
This is what I've done:
Private _Note As New Note.EventNote Public ReadOnly Property Note() As Note.EventNote Get If _Note Is Nothing Then
_Note =
New Note.EventNote End If Return _Note End Get End Property Protected Overrides Sub OnGetChildren(ByVal info As Csla.Serialization.Mobile.SerializationInfo, ByVal formatter As Csla.Serialization.Mobile.MobileFormatter) MyBase.OnGetChildren(info, formatter)info.AddValue(
"_Note", _Note) End Sub Protected Overrides Sub OnSetChildren(ByVal info As Csla.Serialization.Mobile.SerializationInfo, ByVal formatter As Csla.Serialization.Mobile.MobileFormatter) MyBase.OnSetChildren(info, formatter)_Note =
CType(info.Values("_Note").Value, Note.EventNote) End Sub
But I'm running into the same error. I've tried making note inherit a BusinessBase object and mark it as child, but that made no difference. Does this code look ok?
Thanks
I've found the answer to my own question: calling the "AddChild" method rather than "AddValue". For future reference, below is the code that is now working (commented out code is the faild attempt):
Private _Note As New Note.EventNote Public ReadOnly Property Note() As Note.EventNote Get If _Note Is Nothing Then
_Note =
New Note.EventNote End If Return _Note End Get End Property Protected Overrides Sub OnGetChildren(ByVal info As Csla.Serialization.Mobile.SerializationInfo, ByVal formatter As Csla.Serialization.Mobile.MobileFormatter) MyBase.OnGetChildren(info, formatter) Dim fieldManagerInfo = formatter.SerializeObject(_Note)info.AddChild(
"_Note", fieldManagerInfo.ReferenceId) 'info.AddValue("_Note", _Note) End Sub Protected Overrides Sub OnSetChildren(ByVal info As Csla.Serialization.Mobile.SerializationInfo, ByVal formatter As Csla.Serialization.Mobile.MobileFormatter) MyBase.OnSetChildren(info, formatter) Dim childData = info.Children("_Note")_Note =
CType(formatter.GetObject(childData.ReferenceId), Note.EventNote) '_Note = CType(info.Values("_Note").Value, Note.EventNote) End SubCopyright (c) Marimer LLC