web-dev-qa-db-fra.com

Ignorer une propriété pendant la sérialisation XML mais pas pendant la désérialisation

En C #, comment puis-je faire en sorte que XmlSerializer ignore une propriété pendant la sérialisation mais pas pendant la désérialisation? (Ou comment faire la même chose avec Json.net?)

Pour empêcher une propriété d'être sérialisée, vous pouvez ajouter l'attribut XmlIgnore:

[XmlIgnore]
public int FooBar {get;set;}

Cela entraînera l'omission de la balise <FooBar> Lors de la sérialisation.

Cependant, cela signifie également que la balise <FooBar> Sera ignorée lors de la désérialisation.

Dans mon cas, j'accepte un tableau d'éléments de l'utilisateur dans la demande, et pour chaque élément, l'utilisateur peut spécifier une propriété d'action s'il souhaite ajouter, modifier ou supprimer l'élément. Je veux utiliser le même objet modèle pour les appels de liste GET et je ne veux pas renvoyer cette propriété d'action. Je pense que ce serait un cas assez courant.

Un autre cas d'utilisation: disons que vous avez un objet cercle

public class Circle
{
    public double Radius { get; set; }
}

et vous le modifiez pour ajouter une propriété de diamètre

public class Circle2
{
    public double Diameter { get; set; }
    public double Radius { get { return Diameter / 2; } set { Diameter = value*2; } }
}

Vous pouvez vouloir sérialiser uniquement le diamètre, mais toujours être en mesure de désérialiser les fichiers xml dans l'ancien format qui ne contiennent que le rayon.

J'ai fait mes recherches et je n'ai rien trouvé, d'où cette question

Solution : J'ai trouvé la solution. Je peux ajouter une propriété ShouldSerialize qui retourne toujours false, détails à cette documentation MSDN

(cette solution pourrait être ajoutée comme réponse réelle si cette question est rouverte)

46
Manoj

Si vous souhaitez ignorer l'élément lors de la sérialisation avec XmlSerializer, vous pouvez utiliser XmlAttributeOverrides:

XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attribs = new XmlAttributes();
attribs.XmlIgnore = true;
attribs.XmlElements.Add(new XmlElementAttribute("YourElementName"));
overrides.Add(typeof(YourClass), "YourElementName", attribs);

XmlSerializer ser = new XmlSerializer(typeof(YourClass), overrides);
ser.Serialize(...
29
fcuesta

C'est la solution esquissée par Manoj:

Si vous souhaitez supprimer la sérialisation d'une propriété spécifique Foo, mais que vous pouvez toujours la désérialiser, vous pouvez ajouter une méthode public bool ShouldSerializeFoo() qui renvoie toujours false.

Exemple:

public class Circle2
{
    public double Diameter { get; set; }
    public double Radius { get { return Diameter / 2; } set { Diameter = value*2; } }

    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public bool ShouldSerializeRadius() {return false;}
}

Cela empêchera le Radius d'être sérialisé, mais lui permettra tout de même d'être désérialisé.

Cette méthode doit être publique pour que XMLSerializer la trouve, donc afin d'éviter de polluer l'espace de noms, vous pouvez ajouter l'attribut EditorBrowsable pour le cacher de l'IDE. Malheureusement, ce masquage ne fonctionne que si l'assembly est référencé en tant que DLL dans votre projet actuel, mais pas si vous modifiez le projet réel avec ce code.

31
HugoRune