2009-10-25 4 views
0

J'ai un objet InputFile qui a des tableaux et des objets pour contenir le contenu d'un fichier. J'ai aussi ABCFile et XYZFile qui sont tous deux hérités de InputFile qui lira différents types de fichiers et les stocker dans les membres projetés de InputFile.Désérialisation XML d'objets hérités

Étant donné que la sérialisation et la désérialisation de ces deux objets sont identiques à l'objet parent, j'ai implémenté une interface de sérialisation XML standard sur l'objet parent. Lors de la désérialisation, quelques paramètres sont lus, une fonction Read est appelée (pour charger un fichier), puis la désérialisation se termine.

Le sérialisation fonctionne très bien, mais le désérialisation (de List<InputFile>) ne fonctionne pas parce que le désérialiseur appelle les parents, stub Read fonction de fichier au lieu de ABCFile ou XYZFile « s.

Comment puis-je obtenir la désérialisation pour reconnaître le bon type d'objet à utiliser? Il est possible que mon List<InputFile> aura un mélange de types de fichiers.

Merci

Le code que j'utilise pour sérialiser l'objet:

public class InputFileHolder : IXmlSerializable { 
... 
public void WriteXml(XmlWriter w) { 
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
    ns.Add("", ""); 

    XmlSerializer ifXml = new XmlSerializer(typeof(List<InputFile>)); 
    ifXml.Serialize(w, InputFiles, ns); 

    //More serialization 
} 

Toute idée comment maintenir le type d'objet lorsque je sérialiser la liste personnalisée?

Répondre

7

Essayez

[XmlArray] 
[XmlArrayItem(ElementName="ABCFile", Type=typeof(ABCFile))] 
[XmlArrayItem(ElementName="XYZFile", Type=typeof(XYZFile))] 
public List<InputFile> InputFileList 
{ 
    get; 
    set; 
} 

Cela indique le sérialiseur que, bien que ce soit une liste de InputFile, il y aura deux types dérivés qui seront stockés dans cette liste. Il est susceptible de le faire utiliser une version spécifique des méthodes pour chacun.

En cas d'échec, faites le moi savoir.

Modifier en fonction de votre commentaire

Je ne vois pas comment cela peut être happing.

Je l'ai testé les classes suivantes:

public class InputFile 
{ 
    public String InputfileCommonProperty { get; set; } 
} 

public class ABCFile : InputFile 
{ 
    public String ABCSpecificProperty { get; set; } 
} 

public class XYZFile : InputFile 
{ 
    public String XYZSpecificProperty { get; set; } 
} 

public class InputFileHolder 
{ 
    public InputFileHolder() 
    { 
     InputFileList = new List<InputFile>(); 
    } 

    [XmlArray] 
    [XmlArrayItem(ElementName = "ABCFile", Type = typeof(ABCFile))] 
    [XmlArrayItem(ElementName = "XYZFile", Type = typeof(XYZFile))] 
    public List<InputFile> InputFileList { get; set; } 
} 

Mon programme principal ressemble à:

static void Main(string[] args) 
{ 
    InputFileHolder fileHolder = new InputFileHolder(); 
    fileHolder.InputFileList.Add(
     new ABCFile() 
     { 
      InputfileCommonProperty = "This is a common property", 
      ABCSpecificProperty = "This is a class specific property" 
     }); 

    XmlSerializer serializer = new XmlSerializer(typeof(InputFileHolder)); 
    MemoryStream memoryStream = new MemoryStream(); 
    serializer.Serialize(memoryStream, fileHolder); 

    System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); 
    String serializedString = enc.GetString(memoryStream.ToArray()); 
} 

Et à la fin, le contenu de serializedString est:

<?xml version="1.0"?> 
<InputFileHolder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <InputFileList> 
    <ABCFile> 
     <InputfileCommonProperty>This is a common property</InputfileCommonProperty> 
     <ABCSpecificProperty>This is a class specific property</ABCSpecificProperty> 
    </ABCFile> 
    </InputFileList> 
</InputFileHolder> 

Vous voyez? Le sérialiseur sait qu'il s'agit d'un fichier ABCFile et non d'un fichier InputFile générique.

+0

Merci pour la réponse rapide. Le code XML généré ressemble toujours à: . Si je modifie manuellement le fichier XML pour modifier InputFile en fichier ABC, il échoue avec une erreur XML incorrecte. – Aaron

+0

Jetez un oeil à mon extrait de code et dites-moi ce qui se passe –

+0

Ok, il pense que j'ai découvert la racine du problème. Ma version de InputFileHolder a une interface IXmlSerializable où j'ai la lecture/écriture personnalisée des paramètres à sérialiser.Si je supprime l'interface IXmlSerializable et laisse le framework le gérer, j'obtiens du XML comme le vôtre, où le type d'objet est spécifié. J'ai besoin d'avoir une lecture personnalisée, donc j'ai besoin de réparer l'écriture. Je vais ajouter mon code d'écriture dans le message principal. – Aaron