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();
}
}
如果您删除这部分代码,则一切按预期工作:
[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 有一个对象,正如预期的那样。