DataContractSerializer和Generic列表

时间:2014-07-09 11:46:09

标签: c# xml xml-serialization datacontractserializer xml-deserialization

我在从xml文件反序列化列表时遇到问题。我的属性是内部的,所以我使用datacontractserializer而不是xmlserializer。

我的xml如下

<?xml version="1.0" encoding="utf-8" ?>
<Root xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Root">
    <BackgroundColor>
        0,0,255
    </BackgroundColor>
    <RowGap>1</RowGap>
    <Table>
        <TableHeading>"H1"</TableHeading>
        <StartingColumn>A</StartingColumn>
    </Table>
    <Table>
        <TableHeading>"H2"</TableHeading>
        <StartingColumn>B</StartingColumn>
    </Table>    
</Root>

Root有表的列表。 ListOfTables未被反序列化。 课程是

[DataContract()]
public class Root
{
    [OnDeserialized]
    internal void OnSerializingMethod(StreamingContext context)
    {
        if (Table == null)
        {
            Table = new List<TableStructure>();
        }
     }

     [DataMember(Name = "RowGap")]
     internal int RowGap { get; set; }

     [DataMember(Name = "TableHeaderBackgroundColor")]
     internal string HdrBackColor  { get; set; }

     [DataMember()]
     internal List<TableStructure> Table { get; set; }
}

[DataContract(Name = "Table", Namespace = "")]
public sealed class TableStructure 
{
    [DataMember]
    public string TableHeading { get; set; }

    [DataMember]
    public string StartingColumn { get; set; }
}

desrialize方法

internal static Root GetSettings()
{
     Root settings;
     using (FileStream fs = new FileStream("Root.xml", FileMode.Open, FileAccess.Read))
     {
          using (XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas()))
          {
              var x = new DataContractSerializer(typeof(Root));
              settings = (Root)x.ReadObject(reader);
              reader.Close();
              fs.Close();
          }
     }
     return settings;
}

执行时没有任何错误,但不加载任何表信息。正在加载RowGap和颜色

2 个答案:

答案 0 :(得分:4)

我修改了你的解决方案以使其工作(也添加了XML命名空间):

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/Root")]
public class Root
{
    [OnDeserialized]
    internal void OnSerializingMethod(StreamingContext context)
    {
        if (Table == null)
        {
            Table = new List<TableStructure>();
        }
    }

    [DataMember(Name = "RowGap")]
    internal int RowGap { get; set; }

    [DataMember(Name = "TableHeaderBackgroundColor")]
    internal string HdrBackColor { get; set; }

    [DataMember(Name = "Tables")]
    internal List<TableStructure> Table { get; set; }
}

[DataContract(Name = "Table", Namespace = "http://schemas.datacontract.org/2004/07/Root")]
public sealed class TableStructure
{
    [DataMember(Name = "StartingColumn")]
    public string TableHeading { get; set; }

    [DataMember(Name = "TableHeading")]
    public string StartingColumn { get; set; }
}

XML文件:

<?xml version="1.0" encoding="utf-8" ?>
<Root xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Root">
  <BackgroundColor>
    0,0,255
  </BackgroundColor>
  <RowGap>1</RowGap>
  <!-- Used as container element for list -->
  <Tables>
    <Table>
      <!-- Sorted elements alphabetically -->
      <StartingColumn>A</StartingColumn>
      <TableHeading>"H1"</TableHeading>
    </Table>
    <Table>
      <!-- Sorted elements alphabetically -->
      <StartingColumn>B</StartingColumn>
      <TableHeading>"H2"</TableHeading>
    </Table>
  </Tables>
</Root>

注意:此处提到的DataContractSerializer会考虑XML元素的顺序:http://social.msdn.microsoft.com/Forums/vstudio/en-US/a891928b-d27a-4ef2-83b3-ee407c6b9187/order-of-data-members-in-the-xml-string-influences-deserialization-datacontractserializer?forum=wcf。由于您没有按字母顺序对元素进行排序,因此我修改了XML文件以满足DataContractSerializer的行为。

您可以使用DataMember属性及其DataMember.Order属性指定XML元素的顺序。

答案 1 :(得分:1)

你是如何创建xml的?手动还是通过串行器? 围绕现有<Table>元素(代表每个Root.Table实例)应该有一个额外的<Table>元素(代表TableStructure属性)。

这个xml(由DataContractSerializer创建)在我的机器上按预期反序列化:

<Root xmlns="http://schemas.datacontract.org/2004/07/TestDataGrid" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <RowGap>101</RowGap>
    <Table>
        <Table xmlns="">
            <StartingColumn>1</StartingColumn>
            <TableHeading>First</TableHeading>
        </Table>
        <Table xmlns="">
            <StartingColumn>2</StartingColumn>
            <TableHeading>Second</TableHeading>
        </Table>
    </Table>
    <TableHeaderBackgroundColor>c0ffee</TableHeaderBackgroundColor>
</Root>