Partager via


Sérialisation et désérialisation

Windows Communication Foundation (WCF) inclut un nouveau moteur de sérialisation, le DataContractSerializer. Le composant DataContractSerializer traduit entre les objets du .NET Framework et l'XML, dans les deux sens. Cette rubrique explique le fonctionnement du sérialiseur.

Lors de la sérialisation d’objets .NET Framework, le sérialiseur comprend divers modèles de programmation de sérialisation, y compris le nouveau modèle de contrat de données . Pour obtenir la liste complète des types pris en charge, consultez Types pris en charge par le sérialiseur de contrat de données. Pour une présentation des contrats de données, consultez Utilisation de contrats de données.

Lors de la désérialisation du code XML, le sérialiseur utilise les classes XmlReader et XmlWriter. Il prend également en charge les classes XmlDictionaryReader et XmlDictionaryWriter pour permettre de produire du XML optimisé dans certains cas, comme lors de l'utilisation du format XML binaire WCF.

WCF inclut également un sérialiseur complémentaire, le NetDataContractSerializer. NetDataContractSerializer :

  • N’est pas sécurisé. Pour plus d’informations, consultez le Guide de sécurité de BinaryFormatter.
  • Cette fonctionnalité est similaire aux sérialiseurs BinaryFormatter et SoapFormatter, car elle émet également des noms de types .NET Framework dans le cadre des données sérialisées.
  • Est utilisé lorsque les mêmes types sont partagés sur les fins de sérialisation et de désérialisation.

Les deux DataContractSerializer et NetDataContractSerializer proviennent d'une même classe de base, XmlObjectSerializer.

Avertissement

La DataContractSerializer sérialise les chaînes contenant des caractères de contrôle avec une valeur hexadécimale inférieure à 20 sous forme d’entités XML. Cela peut entraîner un problème avec un client non WCF lors de l’envoi de ces données à un service WCF.

Création d’une instance DataContractSerializer

La construction d’une instance du DataContractSerializer fichier est une étape importante. Après la construction, vous ne pouvez pas modifier les paramètres.

Spécification du type racine

Le type racine est le type d’instances sérialisées ou désérialisées. Le constructeur DataContractSerializer a de nombreuses surcharges, mais, au minimum, un type racine doit être fourni en utilisant le paramètre type.

Un sérialiseur créé pour un type racine spécifique ne peut pas être utilisé pour sérialiser (ou désérialiser) un autre type, sauf si le type est dérivé du type racine. L’exemple suivant montre deux classes.

[DataContract]
public class Person
{
    // Code not shown.
}

[DataContract]
public class PurchaseOrder
{
    // Code not shown.
}
<DataContract()> _
Public Class Person
    ' Code not shown.
End Class

<DataContract()> _
Public Class PurchaseOrder
    ' Code not shown.
End Class

Ce code construit une instance de la DataContractSerializer classe qui peut être utilisée uniquement pour sérialiser ou désérialiser des instances de la Person classe.

DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
// This can now be used to serialize/deserialize Person but not PurchaseOrder.
Dim dcs As New DataContractSerializer(GetType(Person))
' This can now be used to serialize/deserialize Person but not PurchaseOrder.

Spécification de types connus

Si le polymorphisme est impliqué dans les types sérialisés qui ne sont pas déjà gérés à l’aide de l’attribut KnownTypeAttribute ou d’un autre mécanisme, une liste de types connus possibles doit être passée au constructeur du sérialiseur à l’aide du knownTypes paramètre. Pour plus d’informations sur les types connus, consultez Types connus du contrat de données.

L’exemple suivant montre une classe, LibraryPatronqui inclut une collection d’un type spécifique, le LibraryItem. La deuxième classe définit le LibraryItem type. Les troisième et quatre classes (Book et Newspaper) héritent de la LibraryItem classe.

[DataContract]
public class LibraryPatron
{
    [DataMember]
    public LibraryItem[] borrowedItems;
}
[DataContract]
public class LibraryItem
{
    // Code not shown.
}

[DataContract]
public class Book : LibraryItem
{
    // Code not shown.
}

[DataContract]
public class Newspaper : LibraryItem
{
    // Code not shown.
}
<DataContract()> _
Public Class LibraryPatron
    <DataMember()> _
    Public borrowedItems() As LibraryItem
End Class

<DataContract()> _
Public Class LibraryItem
    ' Code not shown.
End Class

<DataContract()> _
Public Class Book
    Inherits LibraryItem
    ' Code not shown.
End Class

<DataContract()> _
Public Class Newspaper
    Inherits LibraryItem
    ' Code not shown.
End Class

Le code suivant construit une instance du sérialiseur à l’aide du knownTypes paramètre.

// Create a serializer for the inherited types using the knownType parameter.
Type[] knownTypes = new Type[] { typeof(Book), typeof(Newspaper) };
DataContractSerializer dcs =
new DataContractSerializer(typeof(LibraryPatron), knownTypes);
// All types are known after construction.
' Create a serializer for the inherited types using the knownType parameter.
Dim knownTypes() As Type = {GetType(Book), GetType(Newspaper)}
Dim dcs As New DataContractSerializer(GetType(LibraryPatron), knownTypes)
' All types are known after construction.

Spécification du nom racine et de l’espace de noms par défaut

Normalement, lorsqu’un objet est sérialisé, le nom et l’espace de noms par défaut de l’élément XML le plus externe sont déterminés en fonction du nom et de l’espace de noms du contrat de données. Les noms de tous les éléments internes sont déterminés à partir des noms des membres de données, et leur espace de noms est l’espace de noms du contrat de données. L'exemple suivant définit les valeurs de Name et Namespace dans les constructeurs des classes DataContractAttribute et DataMemberAttribute.

[DataContract(Name = "PersonContract", Namespace = "http://schemas.contoso.com")]
public class Person2
{
    [DataMember(Name = "AddressMember")]
    public Address theAddress;
}

[DataContract(Name = "AddressContract", Namespace = "http://schemas.contoso.com")]
public class Address
{
    [DataMember(Name = "StreetMember")]
    public string street;
}
<DataContract(Name:="PersonContract", [Namespace]:="http://schemas.contoso.com")> _
Public Class Person2
    <DataMember(Name:="AddressMember")> _
    Public theAddress As Address
End Class

<DataContract(Name:="AddressContract", [Namespace]:="http://schemas.contoso.com")> _
Public Class Address
    <DataMember(Name:="StreetMember")> _
    Public street As String
End Class

La sérialisation d’une instance de la Person classe produit du code XML similaire à ce qui suit.

<PersonContract xmlns="http://schemas.contoso.com">  
  <AddressMember>  
    <StreetMember>123 Main Street</StreetMember>  
   </AddressMember>  
</PersonContract>  

Toutefois, vous pouvez personnaliser le nom et l’espace de noms par défaut de l’élément racine en transmettant les valeurs des paramètres rootName et rootNamespace au constructeur DataContractSerializer. Veuillez noter que le rootNamespace n’affecte pas l’espace de noms des éléments contenus qui correspondent aux membres de données. Il affecte uniquement l’espace de noms de l’élément le plus externe.

Ces valeurs peuvent être passées sous forme de chaînes ou d’instances de la XmlDictionaryString classe pour permettre leur optimisation à l’aide du format XML binaire.

Définition du quota maximal d’objets

Certaines surcharges de constructeur DataContractSerializer ont un paramètre maxItemsInObjectGraph . Ce paramètre détermine le nombre maximal d’objets que le sérialiseur peut sérialiser ou désérialiser lors d’un unique appel de méthode ReadObject. (La méthode lit toujours un objet racine, mais cet objet peut avoir d’autres objets dans ses membres de données. Ces objets peuvent avoir d’autres objets, et ainsi de suite.) La valeur par défaut est 65536. Notez que lors de la sérialisation ou de la désérialisation des tableaux, chaque entrée de tableau compte comme objet distinct. Notez également que certains objets peuvent avoir une représentation en mémoire importante et que ce quota seul peut ne pas suffire pour empêcher une attaque par déni de service. Pour plus d’informations, consultez Considérations relatives à la sécurité pour les données. Si vous devez augmenter ce quota au-delà de la valeur par défaut, il est important de le faire à la fois sur les côtés d’envoi (sérialisation) et de réception (désérialisation), car il s’applique à la fois lors de la lecture et de l’écriture de données.

Allers-retours

Un aller-retour se produit lorsqu’un objet est désérialisé et réérialisé en une seule opération. Ainsi, il passe de XML à une instance d’objet, puis de nouveau dans un flux XML.

Certaines surcharges de constructeur DataContractSerializer ont un paramètre ignoreExtensionDataObject , affecté par défaut de la valeur false . Dans ce mode par défaut, les données peuvent être envoyées en aller-retour à partir d’une version plus récente d’un contrat de données via une version antérieure et revenir à la version la plus récente sans perte, tant que le contrat de données implémente l’interface IExtensibleDataObject . Par exemple, supposons que la version 1 du contrat de données contient les membres de données Person et Name, et que la version 2 ajoute les membres PhoneNumber. Si IExtensibleDataObject est implémenté, lors de l’envoi d’informations de la version 2 à la version 1, les données Nickname sont stockées, puis réémises lorsque les données sont sérialisées à nouveau; par conséquent, aucune donnée n’est perdue lors du transfert. Pour plus d’informations, consultez Forward-Compatible contrats de données et gestion des versions des contrats de données.

Problèmes de sécurité et de validité du schéma avec les allers-retours

Les allers-retours peuvent avoir des implications en matière de sécurité. Par exemple, la désérialisation et le stockage de grandes quantités de données superflues peuvent constituer un risque de sécurité. Il peut y avoir des préoccupations de sécurité concernant la réémission de ces données qu’il n’existe aucun moyen de vérifier, en particulier si des signatures numériques sont impliquées. Par exemple, dans le scénario précédent, le point de terminaison version 1 peut signer une Nickname valeur qui contient des données malveillantes. Enfin, il peut y avoir des problèmes de validité de schéma : un point de terminaison peut toujours émettre des données qui respectent strictement son contrat déclaré et non aucune valeur supplémentaire. Dans l’exemple précédent, le contrat du point de terminaison version 1 indique qu’il émet uniquement Name et PhoneNumber, si la validation du schéma est utilisée, l’émission de la valeur supplémentaire Nickname entraîne l’échec de la validation.

Activation et désactivation des allers-retours

Pour désactiver les allers-retours, n’implémentez pas l’interface IExtensibleDataObject . Si vous n'avez aucun contrôle sur les types, définissez le paramètre ignoreExtensionDataObject à true pour obtenir le même effet.

Conservation des graphiques d’objets

Normalement, le sérialiseur ne s’intéresse pas à l’identité de l’objet, comme dans le code suivant.

[DataContract]
public class PurchaseOrder
{
    [DataMember]
    public Address billTo;
    [DataMember]
    public Address shipTo;
}

[DataContract]
public class Address
{
    [DataMember]
    public string street;
}
<DataContract()> _
Public Class PurchaseOrder

    <DataMember()> _
    Public billTo As Address

    <DataMember()> _
    Public shipTo As Address

End Class

<DataContract()> _
Public Class Address

    <DataMember()> _
    Public street As String

End Class

Le code suivant crée une commande d’achat.

// Construct a purchase order:
Address adr = new Address();
adr.street = "123 Main St.";
PurchaseOrder po = new PurchaseOrder();
po.billTo = adr;
po.shipTo = adr;
' Construct a purchase order:
Dim adr As New Address()
adr.street = "123 Main St."
Dim po As New PurchaseOrder()
po.billTo = adr
po.shipTo = adr

Notez que les champs billTo et shipTo sont définis sur la même instance d’objet. Toutefois, le code XML généré duplique les informations déjà dupliquées et ressemble au XML suivant.

<PurchaseOrder>  
  <billTo><street>123 Main St.</street></billTo>  
  <shipTo><street>123 Main St.</street></shipTo>  
</PurchaseOrder>  

Toutefois, cette approche présente les caractéristiques suivantes, qui peuvent être indésirables :

  • Rendement. La réplication des données est inefficace.

  • Références circulaires. Si les objets font référence à eux-mêmes, même par le biais d’autres objets, la sérialisation par réplication entraîne une boucle infinie. (Dans ce cas, le sérialiseur lève une exception SerializationException .)

  • Sémantique. Il est parfois important de conserver le fait que deux références sont au même objet, et non à deux objets identiques.

Pour ces raisons, certaines surcharges de constructeur DataContractSerializer ont un paramètre preserveObjectReferences (la valeur par défaut est false). Lorsque ce paramètre est défini sur true, une méthode spéciale d’encodage des références d’objet, que seul WCF comprend, est utilisée. Lorsque la valeur est définie true, l’exemple de code XML ressemble maintenant à ce qui suit.

<PurchaseOrder ser:id="1">  
  <billTo ser:id="2"><street ser:id="3">123 Main St.</street></billTo>  
  <shipTo ser:ref="2"/>  
</PurchaseOrder>  

L’espace de noms « ser » fait référence à l’espace de noms de sérialisation standard. http://schemas.microsoft.com/2003/10/Serialization/ Chaque élément de données est sérialisé une seule fois et donné un numéro d’ID, et les utilisations suivantes entraînent une référence aux données déjà sérialisées.

Importante

Si les attributs « id » et « ref » sont présents dans le contrat XMLElementde données, l’attribut « ref » est respecté et l’attribut « id » est ignoré.

Il est important de comprendre les limitations de ce mode :

  • Le XML produit par DataContractSerializer avec preserveObjectReferences réglé à true n'est pas interopérable avec d'autres technologies, et ne peut être accessible que par une autre instance de DataContractSerializer, qui a également preserveObjectReferences réglé à true.

  • Il n’existe aucune prise en charge des métadonnées (schéma) pour cette fonctionnalité. Le schéma généré est valide uniquement pour le cas où preserveObjectReferences est défini sur false.

  • Cette fonctionnalité peut entraîner l’exécution plus lente du processus de sérialisation et de désérialisation. Bien que les données ne doivent pas être répliquées, des comparaisons d’objets supplémentaires doivent être effectuées dans ce mode.

Avertissement

Lorsque le preserveObjectReferences mode est activé, il est particulièrement important de définir la maxItemsInObjectGraph valeur sur le quota approprié. En raison de la façon dont les tableaux sont gérés dans ce mode, il est facile pour un attaquant de construire un petit message malveillant qui entraîne une grande consommation de mémoire limitée uniquement par le maxItemsInObjectGraph quota.

Spécification d’un substitut de contrat de données

Certaines surcharges de constructeur DataContractSerializer ont un paramètre dataContractSurrogate qui peut avoir la valeur null. Sinon, vous pouvez l’utiliser pour spécifier un substitut de contrat de données, qui est un type qui implémente l’interface IDataContractSurrogate . Vous pouvez ensuite utiliser l’interface pour personnaliser le processus de sérialisation et de désérialisation. Pour plus d’informations, consultez Les substituts de contrat de données.

Sérialisation

Les informations suivantes s'appliquent à toute classe qui hérite de XmlObjectSerializer, y compris les classes DataContractSerializer et NetDataContractSerializer.

Sérialisation simple

Le moyen le plus simple de sérialiser un objet consiste à le transmettre à la WriteObject méthode. Il y a trois surcharges, chacune pour écrire dans un Stream, un XmlWriterou un XmlDictionaryWriter. Avec la Stream surcharge, la sortie est XML dans l’encodage UTF-8. Avec la XmlDictionaryWriter surcharge, le sérialiseur optimise sa sortie pour le xml binaire.

Lorsque vous utilisez la méthode WriteObject, un sérialiseur utilise le nom et l’espace de noms par défaut pour l’élément enveloppe et l’écrit avec le contenu (voir la section précédente « Spécifiant le nom racine et l’espace de noms par défaut »).

L’exemple suivant illustre l’écriture avec un XmlDictionaryWriter.

Person p = new Person();
DataContractSerializer dcs =
    new DataContractSerializer(typeof(Person));
XmlDictionaryWriter xdw =
    XmlDictionaryWriter.CreateTextWriter(someStream,Encoding.UTF8 );
dcs.WriteObject(xdw, p);
Dim p As New Person()
Dim dcs As New DataContractSerializer(GetType(Person))
Dim xdw As XmlDictionaryWriter = _
    XmlDictionaryWriter.CreateTextWriter(someStream, Encoding.UTF8)
dcs.WriteObject(xdw, p)

Cela produit du code XML similaire à ce qui suit.

<Person>  
  <Name>Jay Hamlin</Name>  
  <Address>123 Main St.</Address>  
</Person>  

ÉtapeBy-Step - Sérialisation

Utilisez les méthodes WriteStartObject, WriteObjectContent et WriteEndObject pour écrire l’élément final, écrire le contenu de l’objet et fermer l’élément enveloppe, respectivement.

Remarque

Il n’existe aucune Stream surcharge de ces méthodes.

Cette sérialisation pas à pas a deux utilisations courantes. Il s’agit d’insérer du contenu tel que des attributs ou des commentaires entre WriteStartObject et WriteObjectContent, comme illustré dans l’exemple suivant.

dcs.WriteStartObject(xdw, p);
xdw.WriteAttributeString("serializedBy", "myCode");
dcs.WriteObjectContent(xdw, p);
dcs.WriteEndObject(xdw);
dcs.WriteStartObject(xdw, p)
xdw.WriteAttributeString("serializedBy", "myCode")
dcs.WriteObjectContent(xdw, p)
dcs.WriteEndObject(xdw)

Cela produit du code XML similaire à ce qui suit.

<Person serializedBy="myCode">  
  <Name>Jay Hamlin</Name>  
  <Address>123 Main St.</Address>  
</Person>  

Une autre utilisation courante consiste à éviter d’utiliser WriteStartObject et WriteEndObject entièrement, et à écrire votre propre élément wrapper personnalisé (ou même ignorer l’écriture d’un wrapper complètement), comme illustré dans le code suivant.

xdw.WriteStartElement("MyCustomWrapper");
dcs.WriteObjectContent(xdw, p);
xdw.WriteEndElement();
xdw.WriteStartElement("MyCustomWrapper")
dcs.WriteObjectContent(xdw, p)
xdw.WriteEndElement()

Cela produit du code XML similaire à ce qui suit.

<MyCustomWrapper>  
  <Name>Jay Hamlin</Name>  
  <Address>123 Main St.</Address>  
</MyCustomWrapper>  

Remarque

L’utilisation de la sérialisation pas à pas peut entraîner un code XML non valide par rapport au schéma.

Désérialisation

Les informations suivantes s'appliquent à toute classe qui hérite de XmlObjectSerializer, y compris les classes DataContractSerializer et NetDataContractSerializer.

La méthode la plus simple pour désérialiser un objet est d'appeler l'une des surcharges de méthode ReadObject . Il y a trois surcharges, chacune pour lire avec un XmlDictionaryReader, un XmlReaderou un Stream. Notez que la Stream surcharge crée un texte XmlDictionaryReader qui n’est protégé par aucun quota et doit être utilisé uniquement pour lire les données approuvées.

Notez également que l’objet retourné par la ReadObject méthode doit être converti en type approprié.

Le code suivant construit une instance du DataContractSerializer et un XmlDictionaryReader, puis désérialise une Person instance.

DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
FileStream fs = new FileStream(path, FileMode.Open);
XmlDictionaryReader reader =
XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());

Person p = (Person)dcs.ReadObject(reader);
Dim dcs As New DataContractSerializer(GetType(Person))
Dim fs As New FileStream(path, FileMode.Open)
Dim reader As XmlDictionaryReader = _
   XmlDictionaryReader.CreateTextReader(fs, New XmlDictionaryReaderQuotas())

Dim p As Person = CType(dcs.ReadObject(reader), Person)

Avant d’appeler la ReadObject méthode, positionnez le lecteur XML sur l’élément wrapper ou sur un nœud non contenu qui précède l’élément wrapper. Pour ce faire, appelez la méthode Read du XmlReader ou de sa dérivation et testez le NodeType, comme illustré dans le code suivant.

DataContractSerializer ser = new DataContractSerializer(typeof(Person),
"Customer", @"http://www.contoso.com");
FileStream fs = new FileStream(path, FileMode.Open);
XmlDictionaryReader reader =
XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
while (reader.Read())
{
    switch (reader.NodeType)
    {
        case XmlNodeType.Element:
            if (ser.IsStartObject(reader))
            {
                Console.WriteLine("Found the element");
                Person p = (Person)ser.ReadObject(reader);
                Console.WriteLine($"{p.Name} {p.Address}    id:{2}");
            }
            Console.WriteLine(reader.Name);
            break;
    }
}
Dim ser As New DataContractSerializer(GetType(Person), "Customer", "http://www.contoso.com")
Dim fs As New FileStream(path, FileMode.Open)
Dim reader As XmlDictionaryReader = XmlDictionaryReader.CreateTextReader(fs, New XmlDictionaryReaderQuotas())

While reader.Read()
    Select Case reader.NodeType
        Case XmlNodeType.Element
            If ser.IsStartObject(reader) Then
                Console.WriteLine("Found the element")
                Dim p As Person = CType(ser.ReadObject(reader), Person)
                Console.WriteLine("{0} {1}", _
                                   p.Name, p.Address)
            End If
            Console.WriteLine(reader.Name)
    End Select
End While

Notez que vous pouvez lire des attributs sur cet élément wrapper avant de passer le lecteur à ReadObject.

Lorsque vous utilisez l’une des surcharges simples ReadObject , le désérialiseur recherche le nom et l’espace de noms par défaut sur l’élément wrapper (voir la section précédente, « Spécification du nom racine et de l’espace de noms par défaut ») et lève une exception s’il trouve un élément inconnu. Dans l’exemple précédent, l’élément <Person> wrapper est attendu. La IsStartObject méthode est appelée pour vérifier que le lecteur est positionné sur un élément nommé comme prévu.

Il existe un moyen de désactiver cette vérification du nom de l’élément wrapper ; Certaines surcharges de la ReadObject méthode acceptent le paramètre verifyObjectNamebooléen, défini true par défaut. Lorsque la valeur est définie false, le nom et l’espace de noms de l’élément wrapper sont ignorés. Cela est utile pour lire du code XML écrit à l’aide du mécanisme de sérialisation pas à pas décrit précédemment.

Utilisation de NetDataContractSerializer

La principale différence entre le DataContractSerializer et le NetDataContractSerializer est que le DataContractSerializer utilise des noms de contrat de données, tandis que le NetDataContractSerializer produit des noms complets d'assembly et de type du .NET Framework dans le XML sérialisé. Cela signifie que les mêmes types doivent être partagés entre les points de terminaison de sérialisation et de désérialisation. Cela signifie que le mécanisme de types connus n'est pas nécessaire avec le NetDataContractSerializer car les types exacts à désérialiser sont toujours connus.

Toutefois, plusieurs problèmes peuvent se produire :

  • Sécurité. Tout type trouvé dans le xml désérialisé est chargé. Cela peut être exploité pour forcer le chargement de types malveillants. L'utilisation de NetDataContractSerializer avec des données non fiables doit s'effectuer uniquement si un binder de sérialisation est utilisé (à l'aide de la propriété ou du paramètre de constructeur Binder ). Le binder autorise uniquement le chargement des types sûrs. Le mécanisme Binder est identique à celui que les types de l’espace de noms System.Runtime.Serialization utilisent.

  • Contrôle de version. L’utilisation de noms de type et d’assembly complets dans le xml limite sévèrement la façon dont les types peuvent être versionnés. Les éléments suivants ne peuvent pas être modifiés : noms de type, espaces de noms, noms d’assembly et versions d’assembly. En définissant le paramètre de propriété ou de constructeur AssemblyFormat à Simple au lieu de la valeur par défaut Full, cela permet des modifications de version d'assemblage, mais pas pour les types de paramètres génériques.

  • Interopérabilité. Étant donné que les noms de type et d’assembly .NET Framework sont inclus dans le code XML, les plateformes autres que .NET Framework ne peuvent pas accéder aux données résultantes.

  • Rendement. L’écriture des noms de type et d’assembly augmente considérablement la taille du code XML résultant.

Ce mécanisme est similaire à la sérialisation binaire ou SOAP utilisée par .NET Framework Remoting (en particulier, BinaryFormatter et SoapFormatter).

L’utilisation du NetDataContractSerializer est similaire à celle de l’élément DataContractSerializer, avec les différences suivantes :

  • Les constructeurs n'exigent pas de spécifier un type racine. Vous pouvez sérialiser n’importe quel type avec la même instance du NetDataContractSerializer.

  • Les constructeurs n’acceptent pas de liste de types connus. Le mécanisme de types connus n’est pas nécessaire si les noms de types sont sérialisés dans le code XML.

  • Les constructeurs n’acceptent pas de substitution de contrat de données. Au lieu de cela, ils acceptent un ISurrogateSelector paramètre appelé surrogateSelector (qui est mappé à la SurrogateSelector propriété). Il s’agit d’un mécanisme de substitution hérité.

  • Les constructeurs acceptent un paramètre appelé assemblyFormat de FormatterAssemblyStyle, qui correspond à la propriété AssemblyFormat. Comme indiqué précédemment, cela peut être utilisé pour améliorer les fonctionnalités de contrôle de version du sérialiseur. Il s’agit d’un mécanisme FormatterAssemblyStyle identique à celui de la sérialisation binaire ou SOAP.

  • Les constructeurs acceptent un StreamingContext paramètre appelé context qui correspond à la Context propriété. Vous pouvez utiliser cela pour passer des informations dans les types qui sont sérialisés. Cette utilisation est identique à celle du StreamingContext mécanisme utilisé dans d’autres System.Runtime.Serialization classes.

  • Les méthodes Serialize et Deserialize sont des alias pour les méthodes WriteObject et ReadObject. Il s’agit de fournir un modèle de programmation plus cohérent avec la sérialisation binaire ou SOAP.

Pour plus d’informations sur ces fonctionnalités, consultez Sérialisation binaire.

Les formats XML que NetDataContractSerializer et DataContractSerializer utilisent ne sont généralement pas compatibles. Autrement dit, toute tentative de sérialiser avec l'un de ces sérialiseurs et de désérialiser avec l'autre n'est pas prise en charge.

Notez également que le NetDataContractSerializer ne génère pas le type complet ni le nom d'assembly complet du .NET Framework pour chaque nœud dans le graphe d'objets. Il génère ces informations uniquement lorsqu’elles sont ambiguës. Autrement dit, il produit au niveau de l’objet racine et pour n'importe quel cas polymorphe.

Voir aussi