C# DataContractSerializer - 反序列化列表列表

本文关键字:列表 反序列化 DataContractSerializer | 更新日期: 2023-09-27 18:31:00

我在反序列化 xml 文件中的列表列表时遇到问题:

<?xml version="1.0" encoding="UTF-8"?>
<RootLevel><!--Container-->
   <ListOfOne><!--List of One -->
      <One>
         <ListOfTwo> <!--List of Two -->
            <Two></Two>
         </ListOfTwo>
      </One>
   </ListOfOne>
</RootLevel>

RootLevel 有一个列表。一个有两个列表

第一级(ListOfOne)是没有任何问题的工作文件,问题是ListOfTwo没有被反序列化

[KnownType(typeof(List<One>))]
    [DataContract(Name = "RootLevel", Namespace = "")]
    public sealed class RootLevel
    {
        [DataMember()]
        public List<One> ListOfOne { get; set; }
        public RootLevel()
        {
            ListOfOne = new List<One>();
        }
    }
[DataContract(Name = "One", Namespace = "")]
    [KnownType(typeof(List<Two>))]
    public sealed class One
    {
        public One()
        {
            ListOfTwo = new List<Two>();
        }
        [OnDeserialized]
        internal void OnSerializingMethod(StreamingContext context)
        {
            ListOfTwo = new List<Two>();
        }
        [DataMember]
        public List<Two> ListOfTwo { get; set; }
}
[DataContract(Name = "Two", Namespace = "")]
    public sealed class Two
    {}

这是操作:

 using (var fs = new FileStream("path to file", FileMode.Open))
            {
                using (var reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas()))
                {
                    DataContractSerializer ser = new DataContractSerializer(typeof(RootLevel));
                    var deserializedPerson = (RootLevel)ser.ReadObject(reader, true);
                    Assert.IsTrue(deserializedPerson.ListOfOne[0].ListOfTwo.Count > 0);
                    reader.Close();
                    fs.Close();
                }
            }

C# DataContractSerializer - 反序列化列表列表

如果您删除这部分代码,则一切按预期工作:

[OnDeserialized]
internal void OnSerializingMethod(StreamingContext context)
    ListOfTwo = new List<Two>();
}

如果您希望确保始终有一个空的 ListOfTwo,请将其更改为:

[OnDeserialized]
internal void OnSerializingMethod(StreamingContext context)
{
    if(ListOfTwo == null) {
        ListOfTwo = new List<Two>();
    }
}

我运行代码时进行了小修改(不是从文件中读取)

string xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
                <RootLevel> <!--Container-->
                   <ListOfOne> <!--List of One -->
                      <One>
                        <ListOfTwo> <!--List of Two -->
                           <Two></Two>
                        </ListOfTwo> 
                     </One>
                   </ListOfOne>
                 </RootLevel>";
var stream = new MemoryStream(Encoding.Default.GetBytes(xml));
using (var reader = XmlDictionaryReader
                           .CreateTextReader(stream, 
                                             new XmlDictionaryReaderQuotas()))
{
    DataContractSerializer ser = new DataContractSerializer(typeof(RootLevel));
    var deserializedPerson = (RootLevel)ser.ReadObject(reader, true);
    Assert.IsTrue(deserializedPerson.ListOfOne[0].ListOfTwo.Count > 0);
    reader.Close();
}

随着此合同的更改

[DataContract(Name = "One", Namespace = "")]
[KnownType(typeof(List<Two>))]
public sealed class One
{
    public One()
    {
        ListOfTwo = new List<Two>();
    }
    [OnDeserialized]
    internal void OnSerializingMethod(StreamingContext context)
    {
        if (ListOfTwo == null)
        {
            ListOfTwo = new List<Two>();
        }
    }
    [DataMember]
    public List<Two> ListOfTwo { get; set; }
}

断言很好,ListOfTwo 有一个对象,正如预期的那样。