2009-12-10 6 views
0

Я пытаюсь десериализовать свой класс, который обычно сериализуется.xml- Deserialize

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: Все плохо!

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

Спасибо, Оксана

+0

Пожалуйста, покажите пример XML. –

+0

Вам нужен публичный сеттер для свойства «Секция», чтобы XmlSerializer мог его заполнить? – David

+0

Это не решает проблему, которую я пробовал с помощью свойства без сеттера, но этот класс был без наследников, десериализация прошла хорошо. (Когда я добавляю свойство, это не наследники, а сами базовые классы, то все хорошо) – Oksana

ответ

-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

0

Вам нужно будет изменить объявление члена частных секций для:

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

В противном случае он будет нулевым и не может быть назначен.

Кроме того, ваша собственность Секции имеет только Getter - она ​​нуждается в сеттера или никогда не будет установлено:

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

    set 
    { 
     this.sections = value; 
    } 

} 
+0

Это не решит проблему. Сеттер не нужен Когда я добавляю в свойство - (у которого есть только сеттер) не наследники, а сами базовые классы, то все хорошо. Но я пытаюсь добавить сеттера, ничего не изменилось. – Oksana

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