如果我的 DataContract 为“IsReference=true”,为什么我不能拥有带有“IsRequired=true”的 DataMember
我有一个类 ClassA
,它有一个属性,其中包含 ClassB
的类型,该属性有一个类型为 ClassA
的字段。当我尝试通过 WCF 序列化它时,由于其递归性质,我遇到了异常。解决方案是将 IsReference=true
添加到 ClassA
的数据协定定义中。
这很棒,除了我有 ClassA
的成员,它们标记有 DataMember(IsRequired=true)
属性,并且一旦我添加了 IsReference=true
然后它抱怨事物不能同时是 IsReference=true
并且具有 IsRequired=true
的成员。
我不明白为什么会这样,我想知道是否有解决方法?
我想声明我的数据成员,以便它们在 xml 中需要?
I have a class, ClassA
which has a property which contains types of ClassB
which has a field which is of Type ClassA
. When I tried to serialize this via WCF I got an exception due to the recursive nature of this. The solution was to add IsReference=true
to the data contract definition of ClassA
.
This is great except I have members of ClassA
which are marked with the DataMember(IsRequired=true)
attribute and once I added the IsReference=true
it then complained that things can't be both IsReference=true
and have members which are IsRequired=true
.
I can't understand why this would be and I would like to know if there is a workaround for this?
I'd like to declare my datamembers so that they required in the xml?
I have seen this post already, but the answer is still not clear to me. If I want to prevent default values from being emitted then I can use the EmitDefaultValues=false along side the IsRequired=true (which is what I want to do anyway). Is there another workaround?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
考虑反序列化场景。您有一堆 DataContractSerializer 正在读入的 XML。假设您正在处理 Foo 类型,该类型标记为 IsReference=true 且 IsRequired=true。
序列化器遇到 Foo 类型的字段 foo1。现在,这意味着 XML 可以表示如下内容:
序列化程序会将 foo1 反序列化为 null,但请记住它引用了一个尚未拥有的对象。序列化器继续反序列化剩余字段。最终,它遇到了另一个领域,如下所示。啊哈,它看到了 foo1 之前引用的对象——ID 为 1 的对象。
当它遇到 id="1" 时,序列化器返回并修复 foo1 以指向 foo2。
但是,foo2 有可能永远不存在。换句话说,foo1 可能引用 XML 中其他任何地方都不存在的 ID。序列化器在完全反序列化图表的其余部分之前无法确定这一点。
我希望你开始看到问题所在。如果某个类型同时是 IsReference 和 IsRequired,则序列化将不再可能保证在反序列化期间将遵循该类型的 IsRequired 性质。如果所需的元素不存在,它不能再快速失败,因为它无法确定它是否存在。
Consider the deserialization scenario. You have a bunch of XML that DataContractSerializer is reading in. Imagine that you are dealing with type Foo, which is marked IsReference=true and IsRequired=true.
The serializer encounters a field foo1 of type Foo. Now, this means that the XML could say something like the followin:
The serializer would deserialize foo1 to null, but remember that it referenced an object it does not yet have. THe serializer goes on to deserialize the remaining fields. Eventually, it encounters another field like the one below. Aha, it sees the object that foo1 referred to earlier -- the object with ID of 1.
When it encounters id="1", the serializer goes back and fixes up foo1 to point to foo2.
However, it is possible for foo2 to never exist. In other words, foo1 could be refering to an ID that does not exist anywhere else in the XML. There is no way for the serializer to know this for sure until it has fully deserialized the rest of the graph.
I hope you begin to see the problem. If a type were both IsReference and IsReequired, it is no longer possible for the serialize to guarantee that the IsRequired nature of the type will be honored during deserialization. It can no longer fail fast if the required element does not exist, because it cannot be sure whether it exists.