xml-反序列化

时间:2009-12-10 19:41:08

标签: c# serialization xml-serialization xml-deserialization

我尝试反序列化我的类,通常是序列化的。

public class MyClass
{
   private List<Section> sections = new List<Section>();
   public List<Section> Sections
   {
        get
        {
          return this.sections;
        }
   }
}

public class Section1: Section
{
    public string MyProperty {get;set;}
}

public class Section2 : Section
{
    public string MyProperty2 {get;set;}
}

我没有错误地序列化MyClass类,但是当我尝试反序列化它时,我在Section中收到了一个带有空属性的类MyClass(此属性为空)!

为什么会这样,如何解决这个问题?

示例xml:

<MyClass>
  <Sections>
     <Section1> 
       <MyProperty>foo1</MyProperty>
     </Section1>
     <Section1> 
       <MyProperty>foo2</MyProperty>
     </Section1>
     <Section2> 
       <MyProperty2>boo1</MyProperty2>
     </Section2>
  </Sections>
</MyClass>

序列化和反序列化代码:

用于序列化/反序列化的类:

public class ObjectSerializer
{
    private readonly XmlAttributeOverrides xmlAttributeOverrides = new XmlAttributeOverrides();

    public void XmlSerialize<T>(T value, TextWriter outStream)
    {
        Type type = typeof (T);
        object[] result = type.GetCustomAttributes(typeof (SerializableAttribute), true);
        if (result != null)
        {
            var serializer = new XmlSerializer(type, this.xmlAttributeOverrides);
            serializer.Serialize(outStream, value);
        }
    }

    public T XmlDeserialize<T>(string xml)
    {
        var textReader = new XmlTextReader(new StringReader(xml));
        var xmlSerializer = new XmlSerializer(typeof(T));

        var result = xmlSerializer.Deserialize(textReader);
        return (T)result;
    }


    public void ExportOverridesFrom<TAssemply, TBaseType, TObject>(
        Expression<Func<TObject, object>> propertySelector)
    {
        IEnumerable<Type> inheritedTypes = typeof (TAssemply).Assembly.GetTypes().Where(t => t.BaseType == typeof (TBaseType));
        var xmlAttributes = new XmlAttributes();
        foreach (Type type in inheritedTypes)
        {
            var xmlElementAttribute = new XmlElementAttribute {Type = type};
            xmlAttributes.XmlElements.Add(xmlElementAttribute);
        }
        PropertyInfo objectProperty = Reflect<TObject>.GetProperty(propertySelector);
        this.xmlAttributeOverrides.Add(typeof (TObject), objectProperty.Name, xmlAttributes);
    }
}

序列化:一切都好!

var objectSerializer = new ObjectSerializer();
objectSerializer.ExportOverridesFrom<Section1, Section, MyClass>(p => p.Sections);
objectSerializer.XmlSerialize(myClass, resultStream);

Deserializatoin:一切都很糟糕!

 xml - result serialization.
 var result = objectSerializer.XmlDeserialize<MyClass>(xml);

谢谢,奥克萨娜

4 个答案:

答案 0 :(得分:0)

在使用之前,您需要将List<Section> sections实例化为空列表。

答案 1 :(得分:0)

您需要将私有部分成员的声明更改为:

private List<Section> sections = new List<Section>();

否则它将为null并且无法分配给。

此外,你的Sections属性只有一个Getter - 它需要一个setter或它永远不会被设置:

public List<Section> Sections
{
    get
    {
      return this.sections;
    }

    set
    {
      this.sections = value;
    }

}

答案 2 :(得分:0)

[DataContract]
[KnownType(typeof(Section1))]
[KnownType(typeof(Section2))]
public class Section
{ 

} 

尝试使用DataContract序列化程序,您可以传入派生类型

序列化:

DataContractSerializer ser = new DataContractSerializer(typeof(Section),new Type[] { typeof(Section1),typeof(Section2)});
     ser.WriteObject(writer, sectionObj);
 writer.Close();

<强>解串行化

DataContractSerializer deser = new DataContractSerializer(typeof(Section),new Type[] { typeof(Section1),typeof(Section2)}););            
Section deserialisedSection = (Section)deser.ReadObject(reader, true);

答案 3 :(得分:-1)

我必须解决这个问题!

何时创建序列化程序,在构造函数中传递xmlAttributeOverrides。 (即与序列化中的相同)。

 public T XmlDeserialize<T>(string xml)
    {
        var textReader = new XmlTextReader(new StringReader(xml));
        var xmlSerializer = new XmlSerializer(typeof(T), xmlAttributeOverrides); <--this

        var result = xmlSerializer.Deserialize(textReader);
        return (T)result;
    }

有效!