Sérialisation
Sérialisation en C#
De nos jours, le langage C# est l’un des plus utilisés pour développer des applications serveur. Une des problématiques les plus souvent rencontrées lors de communications en programmation Web est d’arriver à transférer des objets vers et depuis une application. À cet effet, l’objet doit être transformé dans un format universel. Cette transformation s’appelle la sérialisation. Ce processus permet de récupérer l’objet représenté sous un format échangeable, ce format étant le plus souvent une forme textuelle.
Pour que les données puissent transiter, il faut utiliser un flux de données (appelé stream en anglais, d’où le nom de la classe de base en C# : Stream). Ces flux peuvent prendre plusieurs formes, comme par exemple un flux de données en mémoire (représenté par la classe MemoryStream en C#) ou encore un flux de données vers un fichier sur le disque (représenté par la classe FileStream en C#).
Il existe plusieurs façons de sérialiser un objet, et parmi celles-ci, nous retrouvons les suivantes :
-
La sérialisation XML, qui transforme l’objet en chaîne de caractères au format XML.
-
La sérialisation JSON, qui transforme l’objet en chaîne de caractères...
Sérialisation XML
La sérialisation en XML (eXtensible Markup Language) repose sur un format reconnu comme un standard dans l’industrie. Longtemps utilisé, le XML est un langage de balisage assez verbeux, mais de fait assez puissant et extensible. De nos jours, il est encore utilisé, notamment dans l’approche de fichiers de configuration ou encore de messages d’échanges pour les services utilisant le protocole SOAP.
.NET offre deux façons de gérer la sérialisation, que nous allons couvrir dans cette section. Nous allons commencer par l’approche bas niveau, plus performante, mais également plus contraignante.
1. XmlSerializer
La classe XmlSerializer, qui se trouve dans le namespace System.Xml.Serialization, permet d’effectuer la sérialisation et la désérialisation d’objets en XML. Le fonctionnement de la classe nécessite de fournir un objet ainsi qu’un stream. De même, il est nécessaire de spécifier le type à gérer lors de la création de l’instance de la classe XmlSerializer, en utilisant le mot-clé typeof :
var p = new PersonneXml { Nom = "Mommer", Prenom = "Christophe" };
var serializer = new XmlSerializer(typeof(PersonneXml));
using (var stream = new FileStream("person.xml", FileMode.Create))
{
serializer.Serialize(stream, p);
}
using (var stream = new FileStream("person.xml", FileMode.Open))
{
var p2 = (PersonneXml)serializer.Deserialize(stream);
System.Console.WriteLine("Bonjour " + p2.Nom + " " + p2.Prenom);
}
L’instruction using utilisée dans le bloc de code ci-dessus diffère de l’instruction using utilisée en tête d’un fichier pour importer un espace de noms. Pour plus de détails sur l’utilisation des instructions using dans le code comme ci-dessus, le lecteur peut se référer au chapitre Concepts avancés, section IDisposable et IAsyncDisposable pour mieux comprendre.
La sérialisation avec cette approche repose sur l’utilisation d’attributs permettant de dire ce que nous souhaitons sérialiser ou non...
Sérialisation JSON
Le format de données JSON est de nos jours le plus utilisé pour échanger des informations, du fait de sa simplicité mais également de sa légèreté syntaxique par rapport au XML. De ce fait, le framework .NET permet de traiter nativement le format JSON.
Depuis la version 3 du framework .NET, les ingénieurs de Microsoft ont ajouté directement dans le framework une nouvelle façon de traiter les flux JSON, plus performante que l’approche précédente, et ce afin de ne plus dépendre du package communautaire le plus largement utilisé jusqu’alors : NewtonSoft.Json.
À l’instar de l’API fournie pour le traitement XML, il existe trois approches pour traiter le JSON :
-
De façon procédurale, en lisant le flux de bout en bout à l’aide d’un curseur grâce aux classes Utf8JsonReader et Utf8JsonWriter.
-
Avec une approche orientée document, à l’instar de XDocument, grâce à la classe JsonDocument.
-
De façon extrêmement simplifiée en utilisant la classe statique JsonSerializer.
1. Utf8JsonReader et Utf8JsonWriter
Le format JSON est relativement simple car le type de données rencontré lors de la lecture d’un flux JSON est forcément contenu dans la liste suivante :
-
Début ou fin d’objet
-
Début ou fin de tableau
-
Nom de propriété
-
Valeur (chaîne de caractères, numérique ou booléenne)
De ce fait, l’approche tenue dans la classe Utf8JsonReader se focalise sur la lecture des éléments un par un, et c’est le rôle du développeur de définir ce qu’il souhaite réaliser.
Considérons le flux JSON suivant :
var json = """
{
"Prenom" : "Christophe",
"Nom" : "Mommer",
"Age" : 35,
"Adresse" : {
"Rue": "Place de la comédie",
"Ville" : "Montpellier"
}
}
""";...
Exercice
Le but de cet exercice est de mettre en pratique les différentes formes de sérialisation vues dans cet ouvrage, en lecture comme en écriture.
1. Énoncé
La base de travail est le projet développé au chapitre Programmation orientée objet et au chapitre Algorithmique, à savoir le jeu pour deviner le nombre mystère. Il s’agit de créer ici un tableau de scores qui s’affichera sous le menu du jeu, en proposant au joueur de rentrer son nom s’il entre au palmarès des cinq meilleurs joueurs.
Pour ce faire, il faut calculer un nombre de points correspondant à la formule suivante : nombre de possibilités + (nombre d’essais restant à la puissance difficulté).
Par exemple, si un joueur a tenté de deviner un nombre entre 1 et 100, il y a 100 possibilités. S’il a choisi de jouer en facile, le niveau de difficulté est de 1. Il faut donc mettre le nombre d’essais restants en puissance de ce nombre. Si le joueur a gagné en 4 coups, il lui reste donc 6 manches, ce qui donne 100 + 6 puissance 1 = 106 points.
L’opérateur C# à utiliser pour faire une puissance est ^. Ainsi, pour stocker dans une variable 2 puissance 3, on écrit var i = 2 ^ 3;.
Il faut donc lire le tableau des scores et voir si le joueur peut entrer au palmarès. Si c’est le cas, nous lui demandons la saisie de son nom afin de l’inscrire à la bonne position.
Il n’y a pas de contraintes particulières...