I have a custom base class Entity
decorated with [DataContract(IsReference = true)]
and deriving from UndoableBase
of CSLA.net. Keeping IsReference is important to preserve object reference data.
[Serializable]
[DataContract(IsReference = true)]
public abstract class Entity : UndoableBase
I am getting exception upon serialization using below code snippet:
public void SerializeToFile(string fileName, T obj)
{
_serializer = new DataContractSerializer(typeof(T));
Serialize(fileName, obj);
}
private void Serialize(string fileName, T obj)
{
using (var fs = File.Open(fileName, FileMode.Create))
{
_serializer.WriteObject(fs, obj);
fs.Close();
}
}
System.Runtime.Serialization.InvalidDataContractException
The IsReference setting for type 'Entity' is 'True', but the same setting for its parent class 'Csla.Core.UndoableBase' is 'False'. Derived types must have the same value for IsReference as the base type. Change the setting on type 'Entity' to 'False', or on type 'Csla.Core.UndoableBase' to 'True', or do not set IsReference explicitly.
If I remove this IsReference attribute altogether I start getting following error:
Object graph for type 'XYZ' contains cycles and cannot be serialized if reference tracking is disabled.
Now my question is how to solve it by changing the IsReference
setting for Csla.Core.UndoableBase
during serialization using some API.
While researching on this topic I came across this post, which talks about using DataContractSurrogate
. Please help how to use it specifically if it is helpful in this case or suggest any other technique solving it.
How to serialize class that derives from class decorated with DataContract(IsReference=true)?
After quite a struggle I was finally able to find the answer to this question. There is an overloaded constructor which takes preserveObjectReferences
flag to instruct the serializer to preserve the References. In my case, I have now removed IsReference
annotation from all over and used below overload for serialization and life is good.
var serializer = new DataContractSerializer(typeof(T), knownTypes,
int.MaxValue /*maxObjectsInGraph*/,
false /*ignoreExtensionDataObject*/,
true /*preserveObjectReferences*/,
null /*dataContractSurrogate*/);
Reference: Preserving Object Reference in WCF