循环依赖导致序列化出错

时间:2017-06-24 16:54:08

标签: c# datacontractserializer datacontract csla datacontractsurrogate

我有一个自定义基类Entity,其上饰有[DataContract(IsReference = true)],并来自UndoableBase CSLA.net。保持IsReference对于保留对象引用数据非常重要。

[Serializable]
[DataContract(IsReference = true)]
public abstract class Entity : UndoableBase

我在使用下面的代码片段进行序列化时遇到异常:

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

     

类型'实体'的IsReference设置是真的'但是一样   设置其父类' Csla.Core.UndoableBase'是假的'。   派生类型必须与IsReference具有相同的值作为基础   类型。更改类型'实体'的设置to' False'或类型   ' Csla.Core.UndoableBase'到' True'或者不设置IsReference   明确。

如果我完全删除此IsReference属性,则会开始出现以下错误:

  

类型' XYZ'的对象图包含循环,无法序列化   如果参考跟踪被禁用。

现在我的问题是如何使用某些API在序列化期间更改IsReference的{​​{1}}设置来解决此问题。

在研究这个主题时,我遇到了这篇文章,其中讨论了如何使用Csla.Core.UndoableBase。如果在这种情况下有用,或者建议任何其他解决方法,请帮助如何使用它。

How to serialize class that derives from class decorated with DataContract(IsReference=true)?

1 个答案:

答案 0 :(得分:1)

经过艰苦的斗争,我终于找到了这个问题的答案。有一个重载的构造函数,它使用preserveObjectReferences标志来指示序列化程序保留引用。在我的例子中,我现在已经从全部删除了IsReference注释,并在重载下使用了序列化,生活也很好。

var serializer = new DataContractSerializer(typeof(T), knownTypes,
            int.MaxValue /*maxObjectsInGraph*/,
            false /*ignoreExtensionDataObject*/,
            true /*preserveObjectReferences*/,
            null /*dataContractSurrogate*/);

参考:Preserving Object Reference in WCF