EF DataContractSerializer 异常

发布于 2025-01-08 00:15:37 字数 2167 浏览 0 评论 0原文

我在尝试序列化 EF 4 STE 图表时遇到了一个非常有趣的异常。

      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() 扩展方法,则所有内容都会正常序列化。

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

更新:我找到了一个链接 其他人也有类似的问题。他们说 System.Runtime.Serialization.ObjectReferenceStack.EnsureSetAsIsReference) 正在进行一些循环验证,可能会发现问题。

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

更新 3:最终使用本文 调用重载的 DataContractSerializer 构造函数,并将 keepObjectReferences 设置为 true。这解决了问题,尽管我仍然无法解释它......

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

I've hit a very interesting exception while trying to serialize a graph of 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)

My serialization code is fairly simple:

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();
}

In my object graph, I've added a few child entities to a parent entity, and I've discovered that if I call the .AcceptChanges() extension method on the parent, everything serializes just fine.

Has anyone else encountered something like this? What could be causing it? Any ideas on how I can run down the culprit?

Update: I found a link where someone else had a similar problem. They said that System.Runtime.Serialization.ObjectReferenceStack.EnsureSetAsIsReference) is doing some cycle validation and could be finding a problem.

Update 2: I also found that setting preserveObjectReferences to true in the constructor for the DataContractSerializer clears up the exception.

Update 3: Ended up using approach described in this article to call overloaded DataContractSerializer constructor with preserveObjectReferences set to true. This fixed the issue, although I still can't explain it...

So maybe now, my question becomes: How is preserveObjectReferences on the DataContractSerializer different than having [DataContract(IsReference = true)] on all of the STE's?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

青衫负雪 2025-01-15 00:15:37

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

It seems PreserveObjectReferences uses "non-standard XML constructs" for all your classes, while isReference is the standard SOAP way, but it needs to be declared on every class where it is needed. I had the same problem and it was because I had missed putting it on some classes.
The common trap is that DataContractAttribute is not inherited, so you have to redeclare it (with IsReference=true) for each inherited class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文