【问题标题】:C# DataContractSerializer - Deserialize list of listC# DataContractSerializer - 反序列化列表列表
【发布时间】:2013-09-12 20:25:29
【问题描述】:

我在反序列化 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# xml list datacontractserializer


    【解决方案1】:

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

    [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; }
    }
    

    Assert 没问题,ListOfTwo 有一个预期的对象。

    【讨论】:

    • 请查看我的更新,我正在运行代码并且它可以工作。如果不检查您的 xml 文件,它是否与您的示例匹配。尝试运行我提供的代码。
    • 好的,我会在 V 上打勾,因为它正在工作,谢谢。但奇怪的是,XML 中的 List 必须是第一个,否则它将为空。这是为什么?如果我在列表上方有其他成员测试失败,你能解释一下吗?谢谢!
    • 您是否有测试失败的 Xml 示例?你介意 +1 答案吗?
    • 你改变主意了吗?不再检查
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多