Classe System.Xml.Serialization.XmlSerializer

Cet article vous offre des remarques complémentaires à la documentation de référence pour cette API.

La sérialisation XML est le processus qui consiste à convertir des propriétés et champs publics d'un objet dans un format série (dans ce cas, XML) à des fins de stockage et de transport. La désérialisation recrée l'objet dans son état d'origine à partir du XML. Vous pouvez considérer la sérialisation comme un moyen d’enregistrer l’état d’un objet dans un flux ou une mémoire tampon. Par exemple, ASP.NET utilise la classe XmlSerializer pour encoder des messages de service web XML.

Les données de vos objets sont décrites à l'aide des constructions d'un langage de programmation, telles que les classes, les champs, les propriétés, les types primitifs, les tableaux voire du code XML incorporé sous forme d'objets XmlElement ou XmlAttribute. Vous avez la possibilité de créer vos propres classes, annotées avec des attributs, ou d’utiliser l’outil XML Schema Definition (Xsd.exe) pour générer les classes en fonction d’un document de langage de définition de schéma XML (XSD). Si vous disposez d'un schéma XML, vous pouvez exécuter Xsd.exe pour générer un ensemble de classes fortement typées sur le schéma et annotées avec des attributs pour adhérer au schéma lors de la sérialisation.

Pour transférer des données entre les objets et XML, un mappage des constructions du langage de programmation vers le schéma XML et du schéma XML aux constructions du langage de programmation est nécessaire. Les XmlSerializer et les outils associés tels que Xsd.exe fournissent le pont entre ces deux technologies au moment du design et au moment de l’exécution. Au moment du design, utilisez Xsd.exe pour produire un document de schéma XML (.xsd) à partir de vos classes personnalisées ou pour produire des classes à partir d’un schéma donné. Dans les deux cas, les classes sont annotées avec des attributs personnalisés pour indiquer au XmlSerializer comment mapper entre le système de schéma XML et le Common Language Runtime. Au moment de l’exécution, les instances des classes peuvent être sérialisées dans des documents XML qui suivent le schéma donné. De même, ces documents XML peuvent être désérialisés dans des objets runtime. Notez que le schéma XML est facultatif et non requis au moment du design ou au moment de l’exécution.

Code XML généré par le contrôle

Pour contrôler le code XML généré, vous pouvez appliquer des attributs spéciaux aux classes et aux membres. Par exemple, pour spécifier un autre nom d’élément XML, appliquez une XmlElementAttribute à un champ public ou une propriété, puis définissez la propriété ElementName. Pour obtenir la liste complète des attributs similaires, consultez Attributs qui contrôlent la sérialisation XML. Vous pouvez également implémenter l’interface IXmlSerializable pour contrôler la sortie XML.

Si le code XML généré doit être conforme à la section 5 du document World Wide Consortium, le protocole SOAP 1.1 doit être construit XmlSerializer avec un XmlTypeMapping. Pour contrôler davantage le code XML SOAP encodé, utilisez les attributs répertoriés dans Attributs qui contrôlent la sérialisation SOAP encodée.

Avec le XmlSerializer , vous pouvez tirer parti de l’utilisation de classes fortement typées et avoir toujours la flexibilité du code XML. À l’aide de champs ou de propriétés de type XmlElement, XmlAttribute ou XmlNode dans vos classes fortement typées, vous pouvez lire des parties du document XML directement dans des objets XML.

Si vous utilisez des schémas XML extensibles, vous pouvez également utiliser les attributs XmlAnyElementAttribute et XmlAnyAttributeAttribute pour sérialiser et désérialiser des éléments ou des attributs introuvables dans le schéma d’origine. Pour utiliser les objets, appliquez un XmlAnyElementAttribute à un champ qui retourne un tableau d’objets XmlElement, ou appliquez un XmlAnyAttributeAttribute à un champ qui retourne un tableau d’objets XmlAttribute.

Si une propriété ou un champ retourne un objet complexe (tel qu'un tableau ou une instance de classe), XmlSerializer le convertit en élément imbriqué dans le document XML principal. Par exemple, la première classe du code suivant retourne une instance de la deuxième classe.

Public Class MyClass
    Public MyObjectProperty As MyObject
End Class

Public Class MyObject
    Public ObjectName As String
End Class
public class MyClass
{
    public MyObject MyObjectProperty;
}
public class MyObject
{
    public string ObjectName;
}

La sortie XML sérialisée ressemble à ceci :

<MyClass>
  <MyObjectProperty>
  <ObjectName>My String</ObjectName>
  </MyObjectProperty>
</MyClass>

Si un schéma inclut un élément facultatif (minOccurs = '0'), ou si le schéma inclut une valeur par défaut, vous avez deux options. Une option consiste à utiliser System.ComponentModel.DefaultValueAttribute pour spécifier la valeur par défaut, comme indiqué dans le code suivant.

Public Class PurchaseOrder
    <System.ComponentModel.DefaultValueAttribute ("2002")> _
    Public Year As String
End Class
public class PurchaseOrder
{
    [System.ComponentModel.DefaultValueAttribute ("2002")]
    public string Year;
}

Une autre option consiste à utiliser un modèle spécial pour créer un champ booléen reconnu par le XmlSerializer, et à appliquer la XmlIgnoreAttribute au champ. Le modèle est créé sous la forme de propertyNameSpecified. Par exemple, s’il existe un champ nommé « MyFirstName », vous devriez également créer un champ nommé « MyFirstNameSpecified » qui indique à la classe XmlSerializer s’il faut générer l’élément XML nommé « MyFirstName ». Cela est illustré par l'exemple suivant.

Public Class OptionalOrder
    ' This field's value should not be serialized
    ' if it is uninitialized.
    Public FirstOrder As String

    ' Use the XmlIgnoreAttribute to ignore the
    ' special field named "FirstOrderSpecified".
    <System.Xml.Serialization.XmlIgnoreAttribute> _
    Public FirstOrderSpecified As Boolean
End Class
public class OptionalOrder
{
    // This field should not be serialized
    // if it is uninitialized.
    public string FirstOrder;

    // Use the XmlIgnoreAttribute to ignore the
    // special field named "FirstOrderSpecified".
    [System.Xml.Serialization.XmlIgnoreAttribute]
    public bool FirstOrderSpecified;
}

Remplacer la sérialisation par défaut

Vous pouvez également remplacer la sérialisation de n’importe quel ensemble d’objets, ainsi que leurs champs et propriétés en créant l’un des attributs appropriés et en l’ajoutant à une instance de la classe XmlAttributes. La substitution de la sérialisation de cette façon a deux utilisations : tout d’abord, vous pouvez contrôler et augmenter la sérialisation des objets trouvés dans une DLL, même si vous n’avez pas accès à la source ; deuxièmement, vous pouvez créer un ensemble de classes sérialisables, mais sérialiser les objets de plusieurs façons. Pour plus d’informations, consultez la classe XmlAttributeOverrides et Comment : contrôler la sérialisation de classes dérivées.

Pour sérialiser un objet, appelez la méthode Serialize. Pour désérialiser un objet, appelez la méthode Deserialize.

Pour ajouter des espaces de noms XML à un document XML, consultez XmlSerializerNamespaces.

Remarque

Le XmlSerializer donne un traitement spécial aux classes qui implémentent IEnumerable ou ICollection. Une classe qui implémente IEnumerable doit implémenter une méthode Add publique n'acceptant qu'un paramètre. Le paramètre de la méthode Add doit être du même type que celui retourné par la propriété Current sur la valeur retournée par GetEnumeratorou l’une des bases de ce type. Une classe qui implémente ICollection (par exemple, CollectionBase) en plus de IEnumerable doit avoir une propriété indexée Item publique (indexeur en C#) qui prend un entier et doit avoir une propriété de type entier Count publique. Le paramètre de la méthode Add doit être le même type que celui retourné par la propriété Item, ou l’une des bases de ce type. Pour les classes qui implémentent ICollection, les valeurs à sérialiser sont récupérées à partir de la propriété Item indexée, et non en appelant GetEnumerator.

Vous devez disposer de l’autorisation d’écrire dans le répertoire temporaire (tel que défini par la variable d’environnement TEMP) pour désérialiser un objet.

Assemblies générés dynamiquement

Pour augmenter les performances, l’infrastructure de sérialisation XML génère dynamiquement des assemblies pour sérialiser et désérialiser les types spécifiés. L’infrastructure recherche et réutilise ces assemblies. Ce comportement se produit uniquement lors de l’utilisation des constructeurs suivants :

XmlSerializer.XmlSerializer(Type)

XmlSerializer.XmlSerializer(Type, String)

Si vous utilisez l’un des autres constructeurs, plusieurs versions du même assembly sont générées et ne sont jamais déchargées, ce qui entraîne une fuite de mémoire et des performances médiocres. La solution la plus simple consiste à utiliser l’un des deux constructeurs mentionnés précédemment. Sinon, vous devez mettre en cache les assemblies dans un Hashtable, comme illustré dans l’exemple suivant.

Hashtable serializers = new Hashtable();

// Use the constructor that takes a type and XmlRootAttribute.
XmlSerializer s = new XmlSerializer(typeof(MyClass), myRoot);

// Implement a method named GenerateKey that creates unique keys
// for each instance of the XmlSerializer. The code should take
// into account all parameters passed to the XmlSerializer
// constructor.
object key = GenerateKey(typeof(MyClass), myRoot);

// Check the local cache for a matching serializer.
XmlSerializer ser = (XmlSerializer)serializers[key];
if (ser == null)
{
    ser = new XmlSerializer(typeof(MyClass), myRoot);
    // Cache the serializer.
    serializers[key] = ser;
}

// Use the serializer to serialize or deserialize.
Dim serializers As New Hashtable()

' Use the constructor that takes a type and XmlRootAttribute.
Dim s As New XmlSerializer(GetType([MyClass]), myRoot)

' Implement a method named GenerateKey that creates unique keys
' for each instance of the XmlSerializer. The code should take
' into account all parameters passed to the XmlSerializer
' constructor.
Dim key As Object = GenerateKey(GetType([MyClass]), myRoot)

' Check the local cache for a matching serializer.
Dim ser As XmlSerializer = CType(serializers(key), XmlSerializer)

If ser Is Nothing Then
    ser = New XmlSerializer(GetType([MyClass]), myRoot)
    ' Cache the serializer.
    serializers(key) = ser
End If

' Use the serializer to serialize or deserialize.

Sérialisation de ArrayList et de liste générique

Le XmlSerializer ne peut pas sérialiser ou désérialiser les éléments suivants :

Sérialisation des énumérations de Long non signés

La XmlSerializer ne peut pas être instanciée pour sérialiser une énumération si les conditions suivantes sont remplies : l’énumération est de type long non signé (ulong en C#) et l’énumération contient un membre dont la valeur est supérieure à 9 223 372 036 854 775 807. Par exemple, les éléments suivants ne peuvent pas être sérialisés.

public enum LargeNumbers: ulong
{
    a = 9223372036854775808
}
// At run time, the following code will fail.
xmlSerializer mySerializer=new XmlSerializer(typeof(LargeNumbers));

Types obsolètes

La XmlSerializer classe ne sérialise pas les objets marqués comme [Obsolete].