DataContractSerializer不反序列化对象集合

时间:2016-01-13 21:35:12

标签: c# xml serialization datacontract

晚上好,我有以下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包含“标题”和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对象,但是:

  • 项目“标题”正确反序列化(其值为“MyProject”),
  • 项目“节点”不是(空)。

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

  

对象引用未设置为对象的实例

由于某些奇怪的原因,解串器“无法识别任何节点”。我尝试添加KnownType属性,但没有成功。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

如果您指定NamespaceOrder属性,则此方法有效;否则它会抱怨意外的命名空间或者无法完全读取节点,并且出于某种原因,它期望Title之后的Nodes。{/ p>

[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

  

数据排序的基本规则包括:

     
      
  • 如果数据协定类型是继承层次结构的一部分,则其基本类型的数据成员始终位于订单的第一位。
  •   
  • 接下来按顺序排列当前类型的数据成员,这些成员没有按字母顺序设置DataMemberAttribute属性的Order属性。
  •   
  • 接下来是具有DataMemberAttribute属性集的Order属性的任何数据成员。它们首先按Order属性的值排序,然后按字母顺序排序,如果某个Order值有多个成员。订单值可能会被跳过。
  •   

因为“N”按字母顺序排在“T”之前,所以期望NodeCollection成为第一个。即使事情是“乱序”,它仍然会反序列化(这看起来很奇怪,但这就是它的工作方式) - 它只会用null填充那些对象/成员。