2010-06-14 4 views
0

Je dois sérialiser plusieurs objets héritant de WebControl pour le stockage de base de données. Ceux-ci incluent plusieurs propriétés inutiles (à moi) que je préférerais omettre de la sérialisation. Par exemple BackColor, BorderColor, etc.Omettre les propriétés de la sérialisation WebControl

Voici un exemple de sérialisation XML de l'un de mes contrôles héritant de WebControl.

<Control xsi:type="SerializePanel"> 
     <ID>grCont</ID> 
     <Controls /> 
     <BackColor /> 
     <BorderColor /> 
     <BorderWidth /> 
     <CssClass>grActVid bwText</CssClass> 
     <ForeColor /> 
     <Height /> 
     <Width /> 
     ... 
     </Control> 

J'ai essayé de créer une classe de base commune pour mes contrôles qui hérite de WebControl et utilise l'astuce « xxx Specified » pour choisir de manière sélective ne pas sérialiser certaines propriétés.

Par exemple, pour ignorer une propriété BorderColor vide, je me attends

[XmlIgnore]  
public bool BorderColorSpecified() 
{ 
    return !base.BorderColor.IsEmpty; 
} 

à travailler, mais il n'y a jamais appelé pendant la sérialisation.

Je l'ai également essayé dans la classe à sérialiser ainsi que la classe de base.

Étant donné que les classes elles-mêmes peuvent changer, je préférerais ne pas avoir à créer un sérialiseur personnalisé. Des idées?

Modifier:

J'utilisais déjà XmlAttributeOverrides mais apparemment de manière incorrecte. Je n'ai pas réalisé que vous ne pouviez pas spécifier une classe de base. J'ai peaufiné ma routine, mais ça ne marche toujours pas. Voici quelques détails sur les choses que j'ai essayées.

J'ai WebControl nommé Activity, qui a un ContainerPanel (hérite de Panel) qui contient plusieurs contrôles de type SerializePanel (hérite également de Panel).

Tentative 1 J'ai ajouté les [XmlIgnore] attributs de nouvelles propriétés de SerializePanel n'a pas d'effet. La propriété est toujours incluse dans la sérialisation.

//This is ignored 
[XmlIgnore] 
public new System.Drawing.Color BackColor{ 
get { return base.BackColor; } 
set { }} 

Tentative 2 J'ai essayé aussi le * indiqué dans la déclaration de SerializePanel, mais il a été ignoré

public bool BackColorSpecified 
    { 
     get { return !base.BackColor.IsEmpty; } 
    } 

Tentative 3 Ensuite, dans le sérialiseur j'ai passé les remplacements créés ici :

XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 

string[] serPAnelProps = { "BackColor", "BorderColor", "ForeColor", "Site", "Page", "Parent", "TemplateControl", "AppRelativeTemplateSourceDirectory" }; 
foreach (string strAttr in serPAnelProps) 
{ 
    XmlAttributes ignoreAtrs = new XmlAttributes(); 
    ignoreAtrs.XmlIgnore = true; 
    overrides.Add(typeof(SerializePanel), strAttr, ignoreAtrs); 
} 

string[] ignoreProps = { "Site", "Page", "Parent", "TemplateControl", "AppRelativeTemplateSourceDirectory" }; 
foreach (string strAttr in ignoreProps) 
{ 
    XmlAttributes ignoreAtrs = new XmlAttributes(); 
    ignoreAtrs.XmlIgnore = true; 
    overrides.Add(typeof(System.Web.UI.Control), strAttr, ignoreAtrs); 
} 

Remarque: Les additions d'attribut au type System.Web.UI.Control sont nécessaires pour pouvoir sérialiser un contrôle.

L'extrait XML résultant est pour chaque tentative

<Activity....> 
... 
<ContainerPanel> 
     <ID>actPnl_grAct207_0</ID> 
    - <Controls> 
    - <Control xsi:type="SerializePanel"> 
     <ID>grCont</ID> 
     <Controls /> 
     <BackColor /> 
     <BorderColor /> 
     <BorderWidth /> 
     <CssClass>grActVid</CssClass> 
     <ForeColor /> 
     <Height /> 
     <Width /> 
     <WidthUnitType>Pixel</WidthUnitType> 
     <HeightUnitType>Pixel</HeightUnitType> 
     <WidthUnit>0</WidthUnit> 
     <HeightUnit>0</HeightUnit> 
     </Control> 
... 

Répondre

0

XXXSpecified doit être une propriété, pas une méthode:

public bool BorderColorSpecified 
{ 
    get { return !base.BorderColor.IsEmpty; } 
} 

En outre, l'attribut XmlIgnore est inutile, car en lecture seule la propriété n'est pas sérialisée (et de toute façon c'était une méthode dans votre code)

Alternativement, vous pouvez utiliser un ShouldSerializeXXXméthode au lieu d'une XXXSpecified propriété


EDIT:

Selon la réponse de Marc, l'astuce XXXSpecified ne fonctionnera pas ici ...

Cependant, il y a une autre option disponible pour vous : la classe XmlAttributeOverrides. Cela vous permet de personnaliser la sérialisation sans changer le code de la classe:

XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 

// Ignore the BackColor property 
XmlAttributes attributesBackColor = new XmlAttributes(); 
attributesBackColor.XmlIgnore = true; 
overrides.Add(typeof(WebControl), "BackColor", attributesBackColor); 

// do the same for other properties to ignore... 

XmlSerializer xs = new XmlSerializer(typeof(YourControl), overrides); 

Cette approche est probablement mieux, parce que vous n'avez pas besoin de créer une classe de base commune pour vos commandes. En outre, vous n'avez pas besoin de polluer vos classes avec de nouveaux membres publics qui ne servent à rien sauf la sérialisation

+0

J'apprécie vraiment vos idées. Malheureusement, j'ai toujours des problèmes que je soupçonne liés au fait que j'ai des contrôles imbriqués, bien que ce soit juste un pressentiment à ce stade. Je me demande si vous pourriez prêter attention à ce qui ne va pas encore. Veuillez voir la question éditer. – Laramie

+0

@Laramie, vous devez spécifier l'attribut pour le type sur lequel la propriété est définie. Par exemple, BackColor est défini dans WebControl, pas dans Control. Donc, vous devez écrire 'overrides.Add (typeof (WebControl), strAttr, ignoreAtrs)' –

+0

Cela prend tout son sens. Fonctionne parfaitement pour tous les objets héritant de WebControl, mais je ne vois toujours pas comment sélectionner de manière sélective les types qui héritent de WebControl dont les propriétés doivent être sérialisées. Si je crée une nouvelle propriété publique ** System.Drawing.Color BackColor ** sur un type héritant comme SerializePanel et définissez ** overrides.Add (typeof (SerializePanel), "BackColor", ignoreAtrs) ** BackColor est toujours sérialisé. – Laramie

Questions connexes