EF DataContractSerializer 异常
我在尝试序列化 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看来 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.