对于我们的软件,我必须更改项目整体的 xml 序列化。
几个小时后我发现,如果您实现接口(interface) IXmlSerialized
,则可以修改 xml 序列化。
在阅读了有关如何正确实现此接口(interface)的一些内容后,我已将其实现到实体中。
实现该接口(interface)的实体是一个子类。父类将被序列化为xml。如果子类只是一个普通属性,则序列化是正确的并且工作起来就像一个魅力。 但如果父类有该子类的列表,序列化就会陷入无限循环。
这是一个非常简单的例子来说明我的问题:
public class ParentEntity
{
public List<ChildEntity> Childs { get; set; } = new List<ChildEntity>();
}
public class ChildEntity: IXmlSerializable
{
public string Name { get; set; }
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
Name = reader.GetAttribute("Name");
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("Name", Name);
}
}
这是我用于序列化的逻辑
using (var memoryStream = new MemoryStream())
{
var serializer = new XmlSerializer(typeof(ParentEntity));
serializer.Serialize(memoryStream, parentEntity);
memoryStream.Position = 0;
var deserializedParentEntity = serializer.Deserialize(memoryStream) as ParentEntity;
Console.Read();
}
对象parentEntity
已正确初始化。
然后我将对象序列化为 xml。
之后,我将 xml 反序列化回一个对象(仅用于展示)。
这是我的问题。 ReadXml()
方法经常被调用。它看起来像一个无限循环。我从未到达过的反序列化过程的终点。
有人知道我的问题是什么吗?
最佳答案
如 Proper way to implement IXmlSerializable 中所述,方法 ReadXml()
负责读取整个元素,包括 <ChildEntity>
开始和结束节点,而 WriteXml()
不应该这样做,因为包装器元素是由框架本身编写的。如果ReadXml()
不会让读者超越初始元素,您将得到您所看到的无限循环。
因此你的ChildEntity
类型应如下所示:
public class ChildEntity : IXmlSerializable
{
public string Name { get; set; }
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
Name = reader.GetAttribute("Name");
reader.Skip(); // Consume the <ChildEntity> and </ChildEntity> (if present) nodes and everything contained therein.
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("Name", Name);
}
}
样本fiddle .
关于c# - 自定义xml反序列化陷入死循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40998611/