无法将派生类序列化为XML

时间:2015-03-18 08:37:52

标签: c# .net xml xml-serialization

我正在尝试序列化以下类层次结构:

public class Control
    {
        public virtual string Name {get; set;}

        public virtual string Type {get; set;}

        public virtual string Text { get; set; }

        public virtual SerializableFont Font { get; set; }

        private Operation op = new Operation();
        public Operation Events { get { return op; } }
    }
[System.Xml.Serialization.XmlInclude(typeof(Control))]
    public class TextProperties : Control
    {
        public Label txt;

        public TextProperties()
        {
        }

        public override string Type
        {
            get { return "Text"; }
        }
        public override string Text
        {
            get { return txt.Text; }
            set
            {
                txt.Text = value;
            }
        }
        public override SerializableFont Font
        {
            get { return new SerializableFont(txt.Font); }
            set
            {
                txt.Font = new SerializableFont().Font ;
            }
        }
    }

正如您所看到的,我包括基类但仍然抛出以下异常:

  

不期望TextProperties类型。使用   XmlInclude或SoapInclude属性指定不是的类型   静态地知道。

2 个答案:

答案 0 :(得分:0)

我不确定问题实际上是你的类层次结构本身,似乎没问题。您不需要添加属性。

相反,您可能尝试使用为Control类型的对象创建的XmlSerializer来读取/写入TextProperties类型的对象。这不起作用,您需要使用特定于该类型的序列化程序来序列化/反序列化。

如果在编译时不知道这一点,请尝试创建一个实现IXMLSerializable的包装类。在读取时,此类必须首先读取数据以定义包装对象的类(例如,名为“TypeName”的节点属性)。然后,它必须在运行时为给定类型创建特定的序列化程序,并使用它来加载包装的对象。

编辑:这是一些示例代码,如何完成。您需要自己实现GetTypeByName(例如,遍历所有已加载的程序集或仅将某些字符串“硬连线”到您期望的特定类型)。代码应该足以集成到具有属性“WrappedObject”的类中。

  public XmlSchema GetSchema()
  {
     return null;
  }

  public void ReadXml(XmlReader reader)
  {
     reader.MoveToContent();       
     var typeName = reader.GetAttribute("TypeName");
     reader.ReadStartElement();         
     var serializer = new XmlSerializer(GetTypeByName(typeName));
     WrappedObject = serializer.Deserialize(reader);
     reader.ReadEndElement();
  }

  public void WriteXml(XmlWriter writer)
  {         
     writer.WriteAttributeString("TypeName", "", GetTypeByName(WrappedObject));

     var serializer = new XmlSerializer(typeof(WrappedObject));
     serializer.Serialize(writer, WrappedObject);        
  }

答案 1 :(得分:0)

我认为您需要将属性放在父类之上,如此

[XmlInclude(typeof(ChildClass))] 
[Serializable]
public abstract class ParentClass
{
    public abstract string Name { get; set; }
}

你在儿童班中

[Serializable]
   public class ChildClass: ParentClass
    {   
    }