Silverlight serialization

Silverlight serialization

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


cds posted on Monday, February 23, 2009

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

 

sergeyb replied on Tuesday, February 24, 2009

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

cid:_2_0648EA840648E85C001BBCB886257279
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

 



cds replied on Tuesday, February 24, 2009

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.

swegele replied on Saturday, May 16, 2009

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

swegele replied on Saturday, May 16, 2009

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

abiramipattar replied on Friday, July 31, 2009

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

sergeyb replied on Friday, July 31, 2009

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

cid:_2_0648EA840648E85C001BBCB886257279
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


swegele replied on Friday, July 31, 2009

Actually I forgot to post the much simpler implementation of my DTO after hearing back from Rocky... here it is

[Serializable]
public class Location : Csla.Core.MobileObject
{
public Guid LocationID { get; set; }
public string LocationName { get; set; }
public bool? Staffed24Hours { get; set; }
...
}

Super simple

No IMobileObject to worry about...just inherit from MobileObject and viola!

Sean

FraggleRocks replied on Monday, September 07, 2009

We are using a Criteria object in Silverlight for the first time, and encouter reflection type miss-match errors or the same serialization exception as in this thread.

We took your example but cannot get it to work, can you point us in the right direction especially wrt method parameter types when using a criteria class.

Our code snippet follows (commented out bits show different attempts in desparation!)


public static void NewEquipment(EquipmentIdentityInfo equipmentStruct, EventHandler> handler)
{
var dp = new DataPortal();
dp.CreateCompleted += handler;
//dp.BeginCreate(new EquipmentIdentityInfo { ClientId = equipmentStruct.ClientId, TransactionId = equipmentStruct.TransactionId });
dp.BeginCreate(equipmentStruct);
//dp.BeginCreate(new SingleCriteria(equipmentStruct));
}

#endregion

#if !SILVERLIGHT
//protected void DataPortal_Create(EquipmentIdentityInfo criteria)
protected void DataPortal_Create(SingleCriteria criteria)
{
CreatedUnderTransactionId = criteria.Value.TransactionId;
LoadProperty(CreatedUnderTransactionIdProperty, CreatedUnderTransactionId);
BelongsToClientId = criteria.Value.ClientId;
LoadProperty(BelongsToClientIdProperty, BelongsToClientId);
ValidationRules.CheckRules();
}

[Serializable]
public class EquipmentIdentityInfo : Csla.Core.MobileObject //CriteriaBase
{
/* public EquipmentIdentityInfo(int TransactionId, int ClientId)
{
m_TransactionId = TransactionId;
m_ClientId = ClientId;
}

public EquipmentIdentityInfo()
{

}*/

/* private int m_TransactionId;
public int TransactionId { get { return m_TransactionId; } set { m_TransactionId = value; } }

private int m_ClientId;
public int ClientId { get { return m_ClientId; } set { m_ClientId = value; } }*/
public int TransactionId { get; set;}
public int ClientId { get; set; }
}

cds replied on Monday, September 07, 2009

Hi

I originated the post, and now have CslaLight criteria classes working properly (and my CslaLight app has just been released into production, after 9 months of hard work!)

Anyway, here's a sample complex (i.e. more than one property) criteria class. (If you only have a single property you can use the Csla-provided SingleCriteria class.)

using System;
using Csla;
using Csla.Serialization;
using Csla.Serialization.Mobile;

namespace XXX.XXX.Library.EntityEdit
{
[Serializable]
public class FindLatestPatientStatusCriteria : CriteriaBase
{
public Guid PatientId { get; private set; }
public Guid? ServiceId { get; private set; }

public FindLatestPatientStatusCriteria() { }

public FindLatestPatientStatusCriteria(Guid patientId, Guid? serviceId)
{
PatientId = patientId;
ServiceId = serviceId;
}

protected override void OnGetState(SerializationInfo info, Csla.Core.StateMode mode)
{
info.AddValue("PatientId", PatientId);
info.AddValue("ServiceId", ServiceId);
}

protected override void OnSetState(SerializationInfo info, Csla.Core.StateMode mode)
{
PatientId = info.GetValue("PatientId");
ServiceId = info.GetValue("ServiceId");
}
}
}


I guess the important thing is that you're responsible for adding the properties to the state and retrieving them at the other end.

Does that help? I can post some more code if necessary.

Cheers...

Craig

Adam replied on Tuesday, September 08, 2009

Normal 0 false false false EN-US X-NONE X-NONE MicrosoftInternetExplorer4 /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin-top:0in; mso-para-margin-right:0in; mso-para-margin-bottom:10.0pt; mso-para-margin-left:0in; line-height:115%; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin;}

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

abiramipattar replied on Sunday, August 02, 2009

Hi Sergey,
   I started with the criteria base, but i didn't use the managed backing fields. But, i am not sure if that is the problem in the first place. Because when i used the criteria class derived the criteria base & passed it along either as a SingleCriteria or directly, there was no error, but the values were not coming through when it reaches the Data Portal method. Am not sure what was happening there?

Regards,
Sankar
 

RockfordLhotka replied on Sunday, August 02, 2009

The rules around MobileFormatter are fairly simple.

  1. All types to be serialized must implement IMobileObject.
  2. All field values placed into the serialization stream in the IMobileObject implementation must be basic .NET types (types that are automatically known by the DataContractSerializer)
  3. All child object references placed into the serialization stream by the IMobileObject implementation must implement IMobileObject

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.

abiramipattar replied on Sunday, August 02, 2009

Thanks a ton Rocky. That cleared-up a number of things for me. Maybe, its time for you to write another CSLA book like "1001 things you should know about CSLA.NET" or say "Hardcore CSLA.NET" and compile these little gems you have in these forums with a bit a more detailed commentary so that us low-lifes can lap it up and continue to be lazy ;-)

abiramipattar replied on Sunday, August 02, 2009

Ok. I found out what the problem was. All the members of your criteria class should be basic .NET types. It doesn't even accept SmartDate. Once i did the change, everything was working. Thanks.

Regards,
Sankar

Copyright (c) Marimer LLC