【问题标题】:Custom xml deserialization runs into an endless loop自定义 xml 反序列化陷入死循环
【发布时间】:2016-12-06 15:11:21
【问题描述】:

对于我们的软件,我必须更改项目实体的 xml 序列化。 几个小时后我发现,如果你实现了接口IXmlSerializable,你可以修改xml序列化。

在阅读了有关如何正确实现此接口的一些信息后,我已将其实现到实体中。

实现这个接口的实体是一个子类。父类将被序列化为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() 经常被调用。它看起来像一个无限循环。我从未到达的反序列化过程的终点。

有人知道我的问题是什么吗?

【问题讨论】:

    标签: c# .net xml serialization


    【解决方案1】:

    正如Proper way to implement IXmlSerializable 中解释的那样,方法ReadXml() 负责读取包括&lt;ChildEntity&gt; 开始和结束节点的整个 元素,而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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-09
      • 2010-11-27
      • 2016-02-12
      • 2012-06-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多