2015-12-03 2 views
1

Lors de la désérialisation de XML avec DataContractSerializer Je rencontre des problèmes avec une séquence d'une classe de base. Aucune des classes dérivées sont désérialisée du XML:C# DataContractSerializer avec héritage

<?xml version="1.0" encoding="utf-8" ?> 

<Page xmlns="Renishaw.Page"> 
    <Fields> 
    <Field Value="Welcome"/> 
    <LanguageField Value="English"/> 
    </Fields> 

    <Buttons> 
    <CancelButton/> 
    <BackButton/> 
    <NextButton/> 
    </Buttons> 

    <ChildPath>D:\SerializeTest\Console\bin\Debug\XML\Content\Next\Next\Page.xml</ChildPath> 
</Page> 

Ce qui suit est mon DataContract:

[DataContract(Namespace = "Renishaw.Page")] 
internal class Page 
{ 
    [DataMember(Order=1, IsRequired = true)] 
    public List<Field> Fields { get; set; } 

    [DataMember(Order = 2, IsRequired = true)] 
    public List<Button> Buttons { get; set; } 

    [IgnoreDataMember] 
    public Page Child { get; set; } 

    [DataMember(Order = 3, IsRequired = true)] 
    private string ChildPath { get; set; } 

    [OnDeserialized] 
    private void OnDeserialized(StreamingContext context) 
    { 
     if (ChildPath.Equals("")) 
      return; 

     Child = Serializer.Deserialize<Page>(ChildPath); 
    } 

    [OnSerialized] 
    private void OnSerialized(StreamingContext context) 
    { 

    } 
} 

[DataContract] 
[KnownType(typeof(LanguageField))] 
internal class Field 
{ 
    [DataMember(Order=1)] 
    public string Value { get; set; } 
} 

[DataContract] 
internal class LanguageField : Field 
{ 

} 

[DataContract] 
[KnownType(typeof(BackButton))] 
[KnownType(typeof(CancelButton))] 
[KnownType(typeof(NextButton))] 
internal class Button 
{ 

} 

[DataContract] 
internal class BackButton : Button 
{ 

} 

[DataContract] 
internal class CancelButton : Button 
{ 

} 

[DataContract] 
internal class NextButton : Button 
{ 

} 

Où exactement ce que je me trompe? Existe-t-il un moyen spécifique pour déclarer un contrat pour un article hérité?

Répondre

0

Vous devez ajouter DataContract nom à bouton comme indiqué ci-dessous

[DataContract(Name="ThisIsButton")] 
[KnownType(typeof(BackButton))] 
[KnownType(typeof(CancelButton))] 
[KnownType(typeof(NextButton))] 
internal class Button 
{ 

} 

Et puis ajoutez itype vous xml

<Buttons> 
    <CancelButton itype="ThisIsButton"/> 
    <BackButton itype="ThisIsButton"/> 
    <NextButton itype="ThisIsButton"/> 
    </Buttons> 
+0

Je pense que vous avez raison. L'espace de noms doit être appliqué à chacun des contrats de données, puis i: type peut être ajouté à chacun des types dérivés i.e: