Outils pour utilisateurs

Outils du site


lang:csharp:serialisation

Il faut ajouter la référence System.Runtime.Serialization.

Préparation des classes

[DataContract]
class BatchPoco
{
  [DataMember]
  public String Valeur { get; private set; }
}

Tous les éléments sérialisés doivent être DataContract. Donc si une classe fait référence à une autre classe non native, il faut aussi la déclarer :

[DataContract]
class Class1
{
  [DataMember]
  public String Valeur1 { get; private set; }
}
 
[DataContract]
class Class2
{
  [DataMember]
  public Class1 Valeur2 { get; private set; }
}

On peut aussi avoir des boucles : la classe 1 dépend de la 2 et inversement. Dans ce cas, il faut indiquer qu'il ne faut pas sérialiser tous les éléments mais qu'il faut préserver les références (liens).

[DataContract(IsReference = true)]
class Class1
{
  [DataMember]
  public Class2 Valeur1 { get; private set; }
}
 
[DataContract(IsReference = true)]
class Class2
{
  [DataMember]
  public Class1 Valeur2 { get; private set; }
}

IsReference ne marche qu'avec la sérialisation au format XML, pas JSON.

  • Héritage

Si on souhaite sérialiser une classe dont un des champs n'est renseigné que par un parent ou une interface, il faut déclarer explicitement tous les types de classes.

[DataContract]
class IAnimal{}
 
[DataContract]
class Chat : IAnimal{}
 
[DataContract]
class Chien : IAnimal{}
 
[DataContract]
[KnownType(typeof(Chat))]
[KnownType(typeof(Chien))]
class Foret
{
  [DataMember]
  List<IAnimal> faune;
}

Sans KnownType, il va y avoir une erreur :

Type 'XXXX' with data contract name 'YYYY' is not expected. Add any types not known statically to the list of known types - for example,
by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

Exception during the serialization - Type with data contract name is not expected Archive du 13/05/2015 le 27/04/2020

Understanding Known Types Archive du 22/04/2009 le 27/04/2020

Sérialisation en XML

  • Charger
using (FileStream fs = new FileStream(fileName, FileMode.Open))
{
  DataContractSerializer ser = new DataContractSerializer(typeof(BatchPoco));
  using (XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas()))
  {
    using (MemoryStream ms = new MemoryStream())
    {
      try
      {
        _batch = (BatchPoco)ser.ReadObject(reader, true);
      }
      catch (SerializationException)
      {
        // Fichier non valide.
      }
    }
  }
}
  • Enregistrer
using (MemoryStream ms = new MemoryStream())
{
  DataContractSerializer ser = new DataContractSerializer(typeof(BatchPoco));
  ser.WriteObject(ms, _batch);
  byte[] xml = ms.ToArray();
  using (FileStream fs = new FileStream(fileName, FileMode.Create))
  {
    fs.Write(xml, 0, xml.Length);
  }
}

DataContractSerializer, exemple Archive du 03/30/2017 le 27/04/2020

Sérialisation en JSON

C'est la même chose avec DataContractJsonSerializer.

How to use DataContractJsonSerializer Archive du 25/03/2019 le 27/04/2020

TODO : Cette classe est dépréciée au profit du namespace System.Text.Json.

Initialisation dans le constructeur

Le constructeur, et les propriétés initialisées dans leurs déclarations, ne sont pas appelés lors de la désérialisation. Il est nécessaire de le faire manuellement.

private object Mutex { get; set; };
 
private void InitNoDataMember()
{
  Mutex = new object();
}
 
[OnDeserializing]
private void SetValuesOnDeserializing(StreamingContext context)
{
  InitNoDataMember();
}
 
public Constructeur()
{
  InitNoDataMember();
}

Il existe :

  • OnSerializing : fonction exécutée lors de la sérialisation de l'instance.
  • OnSerialized : fonction exécutée après la sérialisation de l'instance.
  • OnDeserializing : fonction exécutée lors de la désérialisation de l'instance.
  • OnDeserialized : fonction exécutée après la désérialisation de l'instance.

En cas d'héritage, OnSerializing est appelée pour le parent, puis pour l'enfant et enfin les OnSerialized sont appelées. Puis la désérialisation passe à l'objet suivant.

lang/csharp/serialisation.txt · Dernière modification : 2020/04/27 08:39 de root