Hi all
I'm having some serious troubles with (understanding) Silverlight serialization. It's all working OK for my main BO classes but I'm now trying to build a ReadOnlyList which has a complex Criteria object (i.e. not just a single primitive type).
What I'm really trying to accomplish is to have a ReadOnlyList that can be populated by searching on multiple fields. So I've defined a GenericFindParameter class having Field, Operator, and Value string properties. Ideally, I'm wanting to be able to pass a list of these to the ReadOnlyList factory method, but that seems a far off goal at the moment.
So, I've initially tried a single GenericFindParameter.
[
Serializable] public class GenericFindParameter// : IMobileObject{
public string Field { get; set;} public string Operator { get; set; } public string Value { get; set; } public GenericFindParameter(string field, string op, string value){
Field = field;
Operator = op;
Value = value;
}
public GenericFindParameter(){
}
// void IMobileObject.GetState(SerializationInfo info)
// {
// info.AddValue("_field", Field);
// info.AddValue("_operator", Operator);
// info.AddValue("_value", Value);
// }
//
// void IMobileObject.SetState(SerializationInfo info)
// {
// Field = info.GetValue<string>("_field");
// Operator = info.GetValue<string>("_operator");
// Value = info.GetValue<string>("_value");
// }
//
// public void GetChildren(SerializationInfo info, MobileFormatter formatter)
// {
//
// }
//
// public void SetChildren(SerializationInfo info, MobileFormatter formatter)
// {
//
// }
}
You'll see I was implementing IMobileObject, but that didn't help.
In my ReadOnlyList class I have:
public static void GetLookupList(GenericFindParameter p, EventHandler<DataPortalResult<ReadOnlyLookupList>> handler)
{
var dp = new DataPortal<ReadOnlyLookupList>();dp.FetchCompleted += handler;
dp.BeginFetch(
new SingleCriteria<ReadOnlyLookupList, GenericFindParameter>(p));}
When I run this, I get a SerializationException:
Type 'XXX.XXX.Library.GenericFind.GenericFindParameter' with data contract name 'GenericFindParameter:http://schemas.datacontract.org/2004/07/XXX.XXX.Library.GenericFind' 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.
Stack trace:
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at WriteSerializationInfo.FieldDataToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract )
at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at WriteKeyValueOfstringSerializationInfo.FieldDataOzoZvLrmToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract )
at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
at WriteArrayOfKeyValueOfstringSerializationInfo.FieldDataOzoZvLrmToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract )
at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at WriteSerializationInfoToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract )
at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at WriteArrayOfSerializationInfoToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract )
at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph)
at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph)
at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph)
at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph)
at Csla.Serialization.Mobile.MobileFormatter.Serialize(XmlWriter writer, Object graph)
at Csla.Serialization.Mobile.MobileFormatter.Serialize(Stream serializationStream, Object graph)
at Csla.Serialization.Mobile.MobileFormatter.Serialize(Object obj)
at Csla.DataPortalClient.WcfProxy`1.BeginFetch(Object criteria, Object userState)
at Csla.DataPortalClient.WcfProxy`1.BeginFetch(Object criteria)
at Csla.DataPortal`1.BeginFetch(Object criteria)
at XXX.XXX.Library.GenericFind.ReadOnlyLookupList.GetLookupList(GenericFindParameter p, EventHandler`1 handler)
XXX.XXX added to protect the innocent customer :)
So, my question is, how is this meant to work? I understand that I'm meant to handle serialization myself but I'm not understanding exactly when or how. And I'd previously assumed that if my class implemented IMobileObject then it would be called on at the appropriate time to do its serialization.
Can somebody please explain this to me, or point me in the right direction.
Thanks,
Craig
I have seen this error. It appears to result from use of
automatic properties. Compiler creates backing fields with weird name
that confuse XML writer. Please change your properties to use explicit
backing fields and see if the error goes away.
Sergey Barskiy
Principal Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: cds
[mailto:cslanet@lhotka.net]
Sent: Monday, February 23, 2009 9:57 PM
To: Sergey Barskiy
Subject: [CSLA .NET] Silverlight serialization
Hi all
I'm having some serious troubles with (understanding) Silverlight
serialization. It's all working OK for my main BO classes but I'm now
trying to build a ReadOnlyList which has a complex Criteria object (i.e. not
just a single primitive type).
What I'm really trying to accomplish is to have a ReadOnlyList that can be
populated by searching on multiple fields. So I've defined a
GenericFindParameter class having Field, Operator, and Value string properties.
Ideally, I'm wanting to be able to pass a list of these to the ReadOnlyList
factory method, but that seems a far off goal at the moment.
So, I've initially tried a single GenericFindParameter.
[Serializable]
public class GenericFindParameter// :
IMobileObject
{
public string Field { get; set;}
public string Operator { get; set; }
public string Value { get; set; }
public GenericFindParameter(string
field, string op, string
value)
{
Field = field;
Operator = op;
Value = value;
}
public GenericFindParameter()
{
}
// void
IMobileObject.GetState(SerializationInfo info)
// {
//
info.AddValue("_field", Field);
//
info.AddValue("_operator", Operator);
// info.AddValue("_value",
Value);
// }
//
// void
IMobileObject.SetState(SerializationInfo info)
// {
// Field =
info.GetValue<string>("_field");
// Operator =
info.GetValue<string>("_operator");
// Value =
info.GetValue<string>("_value");
// }
//
// public void
GetChildren(SerializationInfo info, MobileFormatter formatter)
// {
//
// }
//
// public void
SetChildren(SerializationInfo info, MobileFormatter formatter)
// {
//
// }
}
You'll see I was implementing IMobileObject, but that didn't help.
In my ReadOnlyList class I have:
public static void GetLookupList(GenericFindParameter
p, EventHandler<DataPortalResult<ReadOnlyLookupList>> handler)
{
var dp = new DataPortal<ReadOnlyLookupList>();
dp.FetchCompleted += handler;
dp.BeginFetch(new
SingleCriteria<ReadOnlyLookupList,
GenericFindParameter>(p));
}
When I run this, I get a SerializationException:
Type 'XXX.XXX.Library.GenericFind.GenericFindParameter' with data contract
name
'GenericFindParameter:http://schemas.datacontract.org/2004/07/XXX.XXX.Library.GenericFind'
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.
Stack trace:
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract
dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean
verifyKnownType, RuntimeTypeHandle declaredTypeHandle)
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator
xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType,
Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator
xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32
declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegator
xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32
declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at WriteSerializationInfo.FieldDataToXml(XmlWriterDelegator ,
Object , XmlObjectSerializerWriteContext , ClassDataContract )
at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator
xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract
dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle
declaredTypeHandle)
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract
dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle
declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator
xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32
declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegator
xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32
declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at WriteKeyValueOfstringSerializationInfo.FieldDataOzoZvLrmToXml(XmlWriterDelegator
, Object , XmlObjectSerializerWriteContext , ClassDataContract )
at
System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator
xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
at WriteArrayOfKeyValueOfstringSerializationInfo.FieldDataOzoZvLrmToXml(XmlWriterDelegator
, Object , XmlObjectSerializerWriteContext , CollectionDataContract )
at
System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator
xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract
dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle
declaredTypeHandle)
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract
dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle
declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator
xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32
declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegator
xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32
declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at WriteSerializationInfoToXml(XmlWriterDelegator , Object ,
XmlObjectSerializerWriteContext , ClassDataContract )
at
System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator
xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract
dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle
declaredTypeHandle)
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract
dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle
declaredTypeHandle)
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator
xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32
declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegator
xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32
declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at WriteArrayOfSerializationInfoToXml(XmlWriterDelegator , Object
, XmlObjectSerializerWriteContext , CollectionDataContract )
at
System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator
xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract
dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle
declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract
dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle
declaredTypeHandle)
at
System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator
writer, Object graph)
at
System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator
writer, Object graph)
at
System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator
writer, Object graph)
at
System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter
writer, Object graph)
at Csla.Serialization.Mobile.MobileFormatter.Serialize(XmlWriter
writer, Object graph)
at Csla.Serialization.Mobile.MobileFormatter.Serialize(Stream
serializationStream, Object graph)
at Csla.Serialization.Mobile.MobileFormatter.Serialize(Object obj)
at Csla.DataPortalClient.WcfProxy`1.BeginFetch(Object criteria,
Object userState)
at Csla.DataPortalClient.WcfProxy`1.BeginFetch(Object criteria)
at Csla.DataPortal`1.BeginFetch(Object criteria)
at
XXX.XXX.Library.GenericFind.ReadOnlyLookupList.GetLookupList(GenericFindParameter
p, EventHandler`1 handler)
XXX.XXX added to protect the innocent customer :)
So, my question is, how is this meant to work? I understand that I'm meant
to handle serialization myself but I'm not understanding exactly when or how.
And I'd previously assumed that if my class implemented IMobileObject then it
would be called on at the appropriate time to do its serialization.
Can somebody please explain this to me, or point me in the right direction.
Thanks,
Craig
Hi Sergey
Thanks for the reply, but no, changing the properties to have manual backing fields makes no difference.
I think I'm fundamentally misunderstanding something here. When I step through the code at the point of serialization, when it serializes the SingleCriteria<B, C> the actual value doesn't get serialized by the MobileFormatter, even though it implements IMobileObject.
In WcfProxy::BeginFetch, it calls:
request.CriteriaData =
MobileFormatter.Serialize(criteria);which is where it falls over.
I think the problem is that the OnGetState method in SingleCriteria just adds its value to the SerializationInfo, assuming it to be a primitive type, which it's not.
So, I guess the solution to my problem would be to implement a custom criteria class that can detect that its "value" implements IMobileObject and then do the appropriate serialization on that.
Sergey et al.
I am also seeing this issue where I can't serialize this dto to the silverlight client
namespace
IRB.DTO{
[
Serializable] public class InvestigatorMEDLicense{
public Guid InvestigatorMEDLicenseID { get; set; } public Guid InvestigatorID { get; set; } public string MEDLicenseState { get; set; } public string MEDLicenseNumber { get; set; } public string MEDLicenseEXPDate { get; set; }}
}
I tried to do what you said to switch to normal properties with a private field and it still doesn't work. I use the XMLSerializer to put this into my DB as snapshots of data so I know that works.
Any ideas?
Sean
OK here is the key...
You have to do BOTH private backing fields AND IMobileObject.
So here is the code that is working
using
System;using
Csla;using
Csla.Serialization;namespace
IRB.DTO{
[
Serializable] public class Investigator : Csla.Serialization.Mobile.IMobileObject{
private Guid _InvestigatorID; public Guid InvestigatorID { get { return _InvestigatorID; } set { _InvestigatorID = value; } } ... etc. void Csla.Serialization.Mobile.IMobileObject.GetState(Csla.Serialization.Mobile.SerializationInfo info){
info.AddValue(
"_InvestigatorID", InvestigatorID);... etc.
}void Csla.Serialization.Mobile.IMobileObject.SetState(Csla.Serialization.Mobile.SerializationInfo info)
{
InvestigatorID = info.GetValue<Guid>("_InvestigatorID");
... etc.
}
public void GetChildren(Csla.Serialization.Mobile.SerializationInfo info, Csla.Serialization.Mobile.MobileFormatter formatter){ }
public void SetChildren(Csla.Serialization.Mobile.SerializationInfo info, Csla.Serialization.Mobile.MobileFormatter formatter){ }
}
}
Thanks guys for all your hard work
Sean
I
would recommend using base criteria class instead of Mobile Object – less
code and you do not need to worry about serialization
[Serializable()]
public
class OrderSearchCriteria
: CriteriaBase
{
private static PropertyInfo<string>
OrderNoProperty = RegisterProperty<string>(typeof(WorkOrderPopupSearchCriteria),
new PropertyInfo<string>("OrderNo",
"Order No", string.Empty));
public string OrderNo
{
get { return
ReadProperty(AMWorkOrderNoProperty); }
}
private static PropertyInfo<string>
OrderHeadlineProperty = RegisterProperty<string>(typeof(WorkOrderPopupSearchCriteria),
new PropertyInfo<string>("OrderHeadline",
"Headline", string.Empty));
public string OrderHeadline
{
get { return
ReadProperty(AMWorkOrderHeadlineProperty); }
}
public OrderSearchCriteria(Type
type, string orderNo, string
headline)
: base(typeof(OrderSearchCriteria))
{
LoadProperty(OrderNoProperty, orderNo);
LoadProperty(OrderHeadlineProperty, headline);
}
public OrderSearchCriteria() { }
}
Sergey Barskiy
Principal Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: abiramipattar
[mailto:cslanet@lhotka.net]
Sent: Friday, July 31, 2009 8:06 AM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] RE: Silverlight serialization
Hi Sergey,
I am getting the same error, even after i do as you have
suggested. Could you please help me with this as i am stuck at the same
scenario that the original post mentioned. Thanks.
Regards,
Sankar
HI Craig
Thanks for your sample code it helped
Hers is what I ended up with – slightly different but essentially the same!
public static void
NewEquipment(EquipmentIdentityInfo
equipmentStruct, EventHandler<DataPortalResult<EquipmentRoot>>
handler)
{
var
dp = new DataPortal<EquipmentRoot>();
dp.CreateCompleted += handler;
dp.BeginCreate(equipmentStruct);
}
#endregion
#if !SILVERLIGHT
protected
void DataPortal_Create(EquipmentIdentityInfo
criteria)
{
CreatedUnderTransactionId =
criteria.TransactionId;
LoadProperty(CreatedUnderTransactionIdProperty,
CreatedUnderTransactionId);
BelongsToClientId =
criteria.ClientId;
LoadProperty(BelongsToClientIdProperty, BelongsToClientId);
ValidationRules.CheckRules();
}
#endif
[Serializable]
public class EquipmentIdentityInfo
: CriteriaBase //Csla.Core.MobileObject
{
public
int TransactionId { get;
private set; }
public
int ClientId { get;
private set; }
public
EquipmentIdentityInfo() { }
public
EquipmentIdentityInfo(int transactionId, int clientId)
{
TransactionId = transactionId;
ClientId = clientId;
}
protected
override void
OnGetState(Csla.Serialization.Mobile.SerializationInfo
info, Csla.Core.StateMode mode)
{
info.AddValue("TransactionId", TransactionId);
info.AddValue("ClientId", ClientId);
}
protected
override void
OnSetState(Csla.Serialization.Mobile.SerializationInfo
info, Csla.Core.StateMode mode)
{
TransactionId =
info.GetValue<int>("TransactionId");
ClientId = info.GetValue<int>("ClientId");
}
}
Please note that the EquipmentIdentityInfo class can be either an internal or external class!
Thanks for the help – Adam and Fraggle Rock/Rob
The rules around MobileFormatter are fairly simple.
If you don't want to manually implement IMobileObject (and I recommend you don't) then you should inherit from MobileObject, MobileList, etc. These all implement IMobileObject for you.
If you use private backing fields you must override OnGetState() and OnSetState() and manually get/set the field values from the serialization stream. Remember that these types must be simple .NET types that are known to the DataContractSerializer.
If you use managed backing fields CSLA .NET does the work for you and you can relax and enjoy the ride. This was the primary reason for inventing managed backing fields.
Copyright (c) Marimer LLC