2010-04-20 3 views
1

L'objectif:propriétés virtuelles dupliqués pendant la sérialisation lorsque l'attribut XmlElement utilisé

XML sérialisation un objet qui contient une liste d'objets de ce type et ses dérivés. Le XML résultant ne doit pas utiliser l'attribut xsi: type pour décrire le type, à savoir les noms des éléments XML sérialisés seraient un nom assigné spécifique au type dérivé, pas toujours celui de la classe de base, qui est le comportement par défaut.

La tentative:

Après avoir exploré IXmlSerializable et IXmlSerializable avec des méthodes de XmlSchemaProvider étranges et de réflexion voodoo de retour des schémas spécialisés et un XmlQualifiedName au cours des jours, je l'ai trouvé, j'ai pu utiliser le simple [XmlElement] attribuer pour atteindre l'objectif ... presque.

Le problème:

propriétés apparaissent deux fois OPPOSER lors de la sérialisation. L'exception lit "L'élément XML 'overriddenProperty' de l'espace de noms '' est déjà présent dans la portée actuelle.Utilisez les attributs XML pour spécifier un autre nom XML ou espace de nom pour l'élément." J'ai essayé d'utiliser une propriété * Specified (voir code), mais cela n'a pas fonctionné.

Exemple de code:

Class Declaration 

using System; 
using System.Collections.Generic; 
using System.Xml.Serialization; 

[XmlInclude(typeof(DerivedClass))] 
public class BaseClass 
{ 
    public BaseClass() { } 

    [XmlAttribute("virt")] 
    public virtual string Virtual 
    { 
     get; 
     set; 
    } 
    [XmlIgnore] 
    public bool VirtualSpecified 
    { 
     get { return (this is BaseClass); } 
     set { } 
    } 

    [XmlElement(ElementName = "B", Type = typeof(BaseClass), IsNullable = false)] 
    [XmlElement(ElementName = "D", Type = typeof(DerivedClass), IsNullable = false)] 
    public List<BaseClass> Children 
    { 
     get; 
     set; 
    } 
} 

public class DerivedClass : BaseClass 
{ 
    public DerivedClass() { } 

    [XmlAttribute("virt")] 
    public override string Virtual 
    { 
     get { return "always return spackle"; } 
     set { } 
    } 
} 

Driver:

BaseClass baseClass = new BaseClass() { 
    Children = new List<BaseClass>() 
}; 
BaseClass baseClass2 = new BaseClass(){}; 
DerivedClass derivedClass1 = new DerivedClass() { 
    Children = new List<BaseClass>() 
}; 
DerivedClass derivedClass2 = new DerivedClass() 
{ 
    Children = new List<BaseClass>() 
}; 

baseClass.Children.Add(derivedClass1); 
baseClass.Children.Add(derivedClass2); 
derivedClass1.Children.Add(baseClass2); 

J'ai la lutte avec et désactiver cette fonction pendant des semaines et ne peut pas trouver la réponse nulle part.

+0

S'il vous plaît Postez le XML résultant. –

Répondre

2

Trouvé.

La solution:

propriétés ornez les outrepassée avec l'attribut [XmlIgnore]. La valeur virtuelle correcte est toujours sérialisée.

Déclaration Classe

using System; 
using System.Collections.Generic; 
using System.Xml.Serialization; 

[XmlInclude(typeof(DerivedClass))] 
public class BaseClass 
{ 
    public BaseClass() { } 

    [XmlAttribute("virt")] 
    public virtual string Virtual 
    { 
     get; 
     set; 
    } 

    [XmlElement(ElementName = "B", Type = typeof(BaseClass), IsNullable = false)] 
    [XmlElement(ElementName = "D", Type = typeof(DerivedClass), IsNullable = false)] 
    public List<BaseClass> Children 
    { 
     get; 
     set; 
    } 
} 

public class DerivedClass : BaseClass 
{ 
    public DerivedClass() { } 

    [XmlAttribute("virt")] 
    [XmlIgnore] 
    public override string Virtual 
    { 
     get { return "always return spackle"; } 
     set { } 
    } 
} 
+0

J'utilise linq2sql et je voudrais aussi "décorer" les classes générées en dehors du fichier généré. Décorer Je veux dire définir certaines propriétés comme étant XmlElement, définir certaines comme XmlIgnore, d'autres comme XmlAttribute, etc. modifier leur nom. J'ai essayé d'utiliser le code ci-dessus, sur une CLASSE PARTIELLE (avec le même nom de la classe linq2sql générée que je veux décorer), mais dans la DerivedClass, j'obtiens cette erreur: Erreur 1 'MyClasses.Data.DerivedClass.id. get ': ne peut pas remplacer le membre hérité' MyClasses.Data.MyObject.id.get 'car il n'est pas marqué virtual, abstract ou override. Même erreur pour "set". Des idées? – firepol

+0

Ceci est une excellente solution si vous avez une classe générée par XSD qui peut se mettre à jour de façon autonome lorsque des mises à jour sont faites dans ce fichier hébergé. Dans le cas où cela se produit plus tôt que plus tard, vous pouvez créer une classe wrapper dérivée qui sert de sauvegarde à l'aide de cette méthode. – Glimpse

Questions connexes