DataContractSerializer 不反序列化对象集合

DataContractSerializer does not deserialize collection of objects

晚上好,我有以下XML:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<project xmlns="">
  <title>MyProject</title>

  <nodes>
    <node>
      <name>base</name>
      <class>BaseNode</class>
    </node>

    <node>
      <name>detail</name>
      <class>DetailNode</class>
    </node>
    ...
  </nodes>
</project>

... 我希望将其反序列化为以下对象结构,以便 Project 包含一个 "Title" 和一个 NodeCollection (后者又包含多个 Node个元素):

[DataContract(Name = "project")]
class Project
{
    [DataMember(Name = "title")]
    public string Title { get; set; }

    [DataMember(Name = "nodes")]
    public NodeCollection Nodes { get; set; }
}

[CollectionDataContract(Name = "nodes", ItemName = "node")]
class NodeCollection : List<Node>
{

}

[DataContract(Name = "node")]
class Node
{
    [DataMember(Name = "name")]
    public string Name { get; set; }

    [DataMember(Name = "class")]
    public string Class { get; set; }
}

使用此架构,反序列化完成且没有错误,返回预期的 Project 对象,但是:

Project 对象上的 Title 属性 设置为预期值,但 NodeCollection 始终为空。事实上,它甚至没有初始化:

Object reference not set to an instance of an object

出于某种奇怪的原因,反序列化器 "does not recognize any nodes"。我尝试添加 KnownType 属性,但没有成功。

我做错了什么?

如果您指定 NamespaceOrder 属性,它会起作用;否则它会抱怨意外的命名空间或无法完全读取节点,并且由于某种原因它期望 TitleNodes.

之后出现
[DataContract(Name = "project", Namespace="")]
public class Project
{
    [DataMember(Name = "title",Order=1)]
    public string Title { get; set; }

    [DataMember(Name = "nodes", Order=2)]
    public NodeCollection Nodes { get; set; }
}

[CollectionDataContract(Name = "nodes",Namespace="", ItemName = "node")]
public class NodeCollection : List<Node> {  }

[DataContract(Name = "node", Namespace="")]
public class Node
{
    [DataMember(Name = "name")]
    public string Name { get; set; }

    [DataMember(Name = "class")]
    public string Class { get; set; }
}

正在查看 documentation

The basic rules for data ordering include:

  • If a data contract type is a part of an inheritance hierarchy, data members of its base types are always first in the order.
  • Next in order are the current type’s data members that do not have the Order property of the DataMemberAttribute attribute set, in alphabetical order.
  • Next are any data members that have the Order property of the DataMemberAttribute attribute set. These are ordered by the value of the Order property first and then alphabetically if there is more than one member of a certain Order value. Order values may be skipped.

因为 "N" 按字母顺序排在 "T" 之前,所以它期望 NodeCollection 排在第一位。即使事情是 "out of order",它仍然会反序列化(这看起来很奇怪,但这就是它的工作原理)——它只会用 null.

填充那些 objects/members