2009-12-10 214 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);