1. Introduction
Rappel : la sérialisation, c'est une façon de sauvegarder l'état d'un objet sous forme de chaîne, fichier ou flux, pour pouvoir ensuite restaurer cet objet (désérialiser) — et on retrouve alors un objet avec les mêmes données.
Situation typique :
1) On a un objet, par exemple un utilisateur avec un nom et un âge.
2) Il faut le sauvegarder — l'envoyer sur le réseau, écrire dans un fichier ou, par exemple, en format JSON.
3) Ensuite on récupère les données depuis la chaîne/le fichier — et on obtient de nouveau l'objet !
En C# ça se fait en quelques lignes. Regardons comment.
Notre application
On développe une petite appli «Gestionnaire de contacts». Supposons qu'on a la classe Person qu'on veut sérialiser.
public class Person
{
// Les propriétés publiques sont nécessaires pour la sérialisation !
public string Name { get; set; }
public int Age { get; set; }
// Le constructeur sans paramètres est requis pour XmlSerializer
public Person() { }
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
Si tu n'es pas familier avec cette syntaxe, t'inquiète — on détaillera les classes et les propriétés plus tard dans le cours. Pour l'instant prends ça comme un modèle de données pour expérimenter. Note : les propriétés publiques Name et Age sont importantes pour la sérialisation, et XmlSerializer nécessite un constructeur public sans paramètres.
2. Sérialisation en JSON avec System.Text.Json
Exemple simple
On l'avait promis — voilà ! Voici à quoi ressemble la sérialisation en JSON :
using System;
using System.Text.Json;
Person person = new Person("Alice", 28);
// Sérialisation : on transforme l'objet en chaîne JSON
string json = JsonSerializer.Serialize(person);
Console.WriteLine("JSON :");
Console.WriteLine(json);
Qu'est-ce qui s'affichera ?
JSON :
{"Name":"Alice","Age":28}
Simple : objet → JSON. Voilà la magie !
Désérialisation — on remet tout en place
Maintenant on fait l'inverse — à partir d'une chaîne JSON on restaure l'objet :
string json = "{\"Name\":\"Bob\",\"Age\":35}";
// Désérialisation : on restaure un objet de type Person depuis la chaîne JSON
Person restored = JsonSerializer.Deserialize<Person>(json);
Console.WriteLine("Objet restauré :");
Console.WriteLine($"Nom: {restored.Name}, âge: {restored.Age}");
Résultat :
Objet restauré :
Nom: Bob, âge: 35
Remarque : si la structure des données ne correspond pas (par exemple il n'y a pas telle propriété), le champ correspondant restera avec la valeur par défaut (null pour les types référence, 0 pour les nombres, etc.).
3. Sérialisation/désérialisation en XML avec XmlSerializer
Sérialisation en XML — premier regard
using System;
using System.IO;
using System.Xml.Serialization;
Person person = new Person("Kate", 22);
// On crée le serializer pour le type Person
var serializer = new XmlSerializer(typeof(Person));
// On écrit le XML dans un fichier
using (var stream = new FileStream("person.xml", FileMode.Create))
{
serializer.Serialize(stream, person);
// Le flux se fermera automatiquement à la fin du using
}
Console.WriteLine("Fichier XML créé !");
Dans le fichier person.xml tu verras quelque chose comme :
<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Kate</Name>
<Age>22</Age>
</Person>
Point important :
Pour écrire dans un fichier on utilise un flux (Stream, par ex. FileStream). Si tu veux sérialiser dans une chaîne (par ex. pour envoyer sur le réseau), utilise StringWriter :
var serializer = new XmlSerializer(typeof(Person));
using (var sw = new StringWriter())
{
serializer.Serialize(sw, person);
string xmlString = sw.ToString();
Console.WriteLine(xmlString);
}
Désérialisation depuis XML
using (var stream = new FileStream("person.xml", FileMode.Open))
{
// N'oublie pas de caster vers le type souhaité !
Person restored = (Person)serializer.Deserialize(stream);
Console.WriteLine($"Nom: {restored.Name}, âge: {restored.Age}");
}
Encore : XmlSerializer exige que la classe sérialisable ait un constructeur public par défaut (sans paramètres).
4. Travailler avec fichiers et chaînes : que choisir ?
Dans la vraie vie la sérialisation peut aller directement dans une chaîne (pour l'envoi via l'API/stockage en BDD) ou dans un fichier (pour stockage long terme).
Sérialisation en chaîne (par ex. pour envoi via API) :
- JSON : on utilise JsonSerializer.Serialize(obj).
- XML : via StringWriter.
Sérialisation en fichier (par ex. export/sauvegarde) :
- JSON : on sauvegarde la chaîne dans un fichier avec les méthodes classiques.
- XML : on écrit directement dans le flux avec XmlSerializer.
Exemple : sérialisation dans un fichier et retour (JSON)
using System.IO;
using System.Text.Json;
Person person = new Person("Tom", 42);
// Sérialisation en chaîne
string json = JsonSerializer.Serialize(person);
// Écriture dans un fichier
File.WriteAllText("contact.json", json);
// Lecture depuis le fichier
string readJson = File.ReadAllText("contact.json");
Person restored = JsonSerializer.Deserialize<Person>(readJson);
Console.WriteLine($"{restored.Name}, âge: {restored.Age}");
5. Comparaison JSON vs XML
Visualisation du processus
Pour ne pas se perdre, voici le schéma du processus de sérialisation et désérialisation :
flowchart LR
A[Objet] -- sérialisation --> B[Chaîne/Fichier/Flux]
B -- désérialisation --> C[Objet]
A -. JSON ou XML .-> B
B -. JSON ou XML .-> C
Tu peux imaginer que la sérialisation, c'est "faire sa valise", et la désérialisation, "déballer à la maison".
Tableau comparatif
| Fonctionnalité | JSON (System.Text.Json) | XML (XmlSerializer) |
|---|---|---|
| Lecture/écriture en chaîne | ++ | + |
| Lecture/écriture de fichier | ++ | ++ |
| Nécessite un constructeur sans paramètres | Non | Oui |
| Lisibilité pour un humain | ++ | + |
| Schéma de données strict (validation) | - | ++ |
| Flexibilité (attributs de customisation) | + | ++ |
| Performance | ++ | + |
| Compatibilité avec Internet | ++ | + |
++ — très bien, + — OK, - — non supporté
6. Comment ajouter la sérialisation dans notre appli
Supposons que le «Gestionnaire de contacts» doit pouvoir sauvegarder la liste des contacts dans un fichier et la restaurer.
Contexte : on a une liste de contacts (List<Person>).
List<Person> contacts = new List<Person>
{
new Person("Basil", 30),
new Person("Peter", 25),
new Person("Mary", 27)
};
// On sauvegarde tous les contacts — sérialisation en JSON
string jsonContacts = JsonSerializer.Serialize(contacts);
File.WriteAllText("contacts.json", jsonContacts);
// On restaure la liste de contacts
string readContactsJson = File.ReadAllText("contacts.json");
List<Person> restored = JsonSerializer.Deserialize<List<Person>>(readContactsJson);
foreach (var c in restored)
{
Console.WriteLine($"{c.Name}, âge: {c.Age}");
}
On peut faire la même chose avec XML, mais il y a des particularités. Pour sérialiser des collections avec XmlSerializer, on entoure souvent la liste d'une classe conteneur (élément racine) — c'est plus simple pour contrôler le format et les noms des éléments.
7. Erreurs typiques lors de la sérialisation et désérialisation
Erreur n°1 : mismatch de types lors de la sérialisation/désérialisation.
Si tu as sérialisé une List<Person>, il faut désérialiser aussi en List<Person>, pas en List<object> ou IEnumerable<Person>. Sinon tu auras une erreur ou des résultats inattendus.
Erreur n°2 : tentative de sérialiser des champs ou propriétés non publics.
Les sérialiseurs typiques (JsonSerializer, XmlSerializer) travaillent avec les membres publics. Si une propriété n'a pas de getter/setter public, la valeur peut ne pas apparaître dans le JSON/XML, et tu te demanderas pourquoi c'est null.
Erreur n°3 : absence du constructeur sans paramètres.
Pour XmlSerializer le constructeur public par défaut est obligatoire. S'il manque — il y aura une exception lors de la désérialisation.
Erreur n°4 : mauvaise compréhension des références d'objets.
Si un objet contient une référence vers un autre, la sérialisation se fait "par valeur" (comme un objet imbriqué). Les références elles-mêmes ne sont pas conservées, ce qui peut provoquer des duplications de données ou des problèmes avec des références cycliques.
Erreur n°5 : tenter de mélanger les formats de sérialisation.
XML et JSON sont des formats différents avec des sérialiseurs différents. Tu ne peux pas passer une chaîne JSON à XmlSerializer et vice versa — ça provoquera une erreur.
GO TO FULL VERSION