EF DataContractSerializer异常

时间:2012-02-21 13:02:32

标签: c# .net wcf entity-framework datacontractserializer

在尝试序列化EF 4 STEs图时,我遇到了一个非常有趣的例外。

      System.IndexOutOfRangeException was caught
      Message=Index was outside the bounds of the array.
      Source=mscorlib
      StackTrace:
        Server stack trace: 
           at System.Runtime.Serialization.ObjectReferenceStack.EnsureSetAsIsReference(Object obj)
           at System.Runtime.Serialization.XmlObjectSerializerWriteContext.OnHandleIsReference(XmlWriterDelegator xmlWriter, DataContract contract, Object obj)
           at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
           ...
           at System.Runtime.Serialization.XmlObjectSerializer.WriteObject(XmlDictionaryWriter writer, Object graph)
           at System.Runtime.Serialization.XmlObjectSerializer.WriteObject(Stream stream, Object graph)

我的序列化代码非常简单:

using (MemoryStream memoryStream = new MemoryStream())
{
    DataContractSerializer dc = new DataContractSerializer(data.GetType());
    dc.WriteObject(memoryStream, data);

    memoryStream.Flush();

    memoryStream.Position = 0;
    StreamReader reader = new StreamReader(memoryStream);
    var serializedObject = reader.ReadToEnd();
}

在我的对象图中,我已经向父实体添加了一些子实体,并且我发现如果我在父实体上调用.AcceptChanges()扩展方法,那么所有序列化都很好。

还有其他人遇到过这样的事吗?可能是什么原因造成的?关于如何解决罪魁祸首的任何想法?

更新:我发现了link其他人遇到类似问题。他们说System.Runtime.Serialization.ObjectReferenceStack.EnsureSetAsIsReference)正在做一些循环验证,可能会发现问题。

更新2:我还发现在DataContractSerializer的构造函数中将preserveObjectReferences设置为true可以清除异常。

更新3:使用this article中描述的方法结束调用重载的DataContractSerializer构造函数,并将preserveObjectReferences设置为true。这解决了这个问题,虽然我还是无法解释它......

所以也许现在,我的问题变成: DataContractSerializer上的preserveObjectReferences与所有STE上的[DataContract(IsReference = true)]有何不同?

谢谢!

1 个答案:

答案 0 :(得分:1)

似乎PreserveObjectReferences对所有类使用“非标准XML构造”,而isReference是标准的SOAP方式,但需要在需要它的每个类上声明它。我有同样的问题,因为我错过了把它放在某些课程上。 常见陷阱是DataContractAttribute不是继承的,因此您必须为每个继承的类重新声明它(使用IsReference = true)。