2009-12-10 146 views
0

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

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的没有错误,但是当我尝试反序列化,我在科收到了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:Everything bad!

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

感谢,奥克萨娜

+0

请出示例如XML。 – 2009-12-10 19:43:06

+0

您是否需要“Section”属性的公共setter以便XmlSerializer可以填充它? – David 2009-12-10 19:56:12

+0

它并没有解决问题,我试图与财产没有一个setter,但这个班没有继承人,反序列化进展顺利。 (当我添加一个属性不是继承人,并且他们自己的基类,那么一切都很好) – Oksana 2009-12-10 20:15:39

回答

-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; 
    } 

它的工作!

0

你需要的List<Section> sections实例化一个空的列表中,您使用它之前。

+0

我实例化一个属性,但结果是一样的 – Oksana 2009-12-10 19:56:46

0

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

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

否则将是无效和无法被分配到。

此外,您的第属性只具有一个getter - 它需要一个二传手或者它永远不会设置:我有

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

    set 
    { 
     this.sections = value; 
    } 

} 
+0

它不能解决问题。不需要安装程序 当我添加属性 - (只有一个setter)而不是继承者,并且基类本身时,一切都很好。 但我尝试添加一个setter,没有任何改变。 – Oksana 2009-12-10 20:38:13

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);