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 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. [[https://stackoverflow.com/questions/30210393/exception-during-the-serialization-type-with-data-contract-name-is-not-expecte/30214583|Exception during the serialization - Type with data contract name is not expected]] {{ :lang:csharp:serialisation:c_-_exception_during_the_serialization_-_type_with_data_contract_name_is_not_expected_-_stack_overflow_2020-04-27_8_18_17_am_.html |Archive du 13/05/2015 le 27/04/2020}} [[https://docs.microsoft.com/en-us/archive/blogs/youssefm/understanding-known-types/|Understanding Known Types]] {{ :lang:csharp:serialisation:understanding_known_types_microsoft_docs_2020-04-27_8_18_33_am_.html |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); } } [[https://docs.microsoft.com/fr-fr/dotnet/framework/wcf/samples/datacontractserializer-sample|DataContractSerializer, exemple]] {{ :lang:csharp:serialisation:datacontractserializer_exemple_-_wcf_microsoft_docs_2020-04-27_8_18_42_am_.html |Archive du 03/30/2017 le 27/04/2020}} ====Sérialisation en JSON==== C'est la même chose avec ''DataContractJsonSerializer''. [[https://docs.microsoft.com/fr-fr/dotnet/framework/wcf/feature-details/how-to-serialize-and-deserialize-json-data|How to use DataContractJsonSerializer]] {{ :lang:csharp:serialisation:comment_utiliser_datacontractjsonserializer_-_wcf_microsoft_docs_2020-04-27_8_19_16_am_.html |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.