Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Cross-plateforme, stockage ou Web : Sérialisation JSON

[new:15/01/2013]La sérialisation des données est à la programmation Objet ce que le jerrycan est à l’essence : si vous n’avez pas le premier vous ne pouvez pas transporter ni conserver le second. Or sérialiser n’est pas si simple, surtout lorsqu’on souhaite un format lisible et cross-plateforme. JSON est alors une alternative à considérer.

Pourquoi sérialiser ?

Les raisons sont infinies, mais le but général reste le même : transporter ou stocker l’état d’un objet (ou d’une grappe d’objets). C’est donc un processus qui s’entend forcément en deux étapes : la sérialisation proprement-dite et la désérialisation sans laquelle la première aurait autant d’intérêt qu’une boîte de conserve sans ouvre-boîte…

On sérialise les objets pour les transmettre à un service, on désérialise pour consommer ses objets via des services, on peut aussi se servir de la sérialisation comme d’un moyen pratique pour stocker l’état d’une page sous Windows Phone ou Windows 8 par exemple. En effet, une sérialisation de type chaîne (XML ou JSON) à l’avantage de n’être que du texte, un simple texte. Plus de références, de memory leaks, ou autres problèmes de ce type. Les objets ayant été sérialisés peuvent être supprimés de la mémoire, ils pourront être recréés plus tard. Réhydratés comme un potage instantané… De plus une chaîne de caractères cela se traite, se transmet, se stocke très facilement et cela supporte aussi avec un taux de réussite souvent impressionnant la compression (Zip par exemple).

Il existe donc des milliers de raisons de vouloir sérialiser des objets (ou de consommer des objets lyophilisés préalablement par une sérialisation).

Choisir le moteur de sérialisation

Une des forces du Framework .NET a été, dès le début, de proposer des moteurs de sérialisation efficace, à une époque où d’autres langages et environnement peinaient à le faire. La sérialisation binaire a petit à petit cédé la place à la sérialisation XML, format devenu incontournable avec l’avènement du Web et des Web services.

.NET s’acquitte toujours de cette tâche de façon efficace d’ailleurs.

Mais alors pourquoi aller chercher plus loin ?

D’une part parce que les modes changes sans véritable raison technique, ainsi JSON est un format plus “hype” que XML ces temps-ci. Vous allez me dire, “je m’en fiche”. Oui, bien sur. Moi aussi. Ma la question n’est pas là. Il se trouve qu’il existe donc de plus en plus de services qui fournissent leurs données en JSON et qu’il faut bien pouvoir les interpréter pour les consommer… Realpolitik.

D’autres facteurs méritent malgré tout d’être pris en compte : notamment les capacités du moteur de sérialisation lui-même. Car tous ne sont pas égaux ! Certains, comme ceux du Framework .NET refusent les références circulaires par exemple…

Je sais que dit comme ça, les références circulaires on peut penser ne jamais en faire, mais il existe des tas de situations très simples et légitimes qui pourtant peuvent en voir surgir. Et il n’est pas “normal” d’avoir à “bricoler” les propriétés d’un objet pour que la plateforme technique puisse fonctionner. A fortiori lorsqu’on vise du cross-plateforme où la solution peut avoir à être implémentée chaque fois de façon différente.

Bien entendu les différences ne s’arrêtent pas là, certains moteurs savent gérer la sérialisation et la désérialisation des types anonymes ou des types dynamiques, d’autres non. Et les nuances de ce genre ne manquent pas !

Mieux vaut donc choisir son moteur de sérialisation correctement.

Il existe ainsi de bonnes raisons d’avoir, à un moment ou un autre, besoin d’un autre moteur de sérialisation que celui offert par .NET.

JSON.NET

C’est le moteur de sérialisation JSON peut-être le plus utilisé sous .NET, la librairie est bien faite, performante (plus que .NET en JSON en tout cas) et totalement portable entre les différentes versions de .NET. Le projet est open source sur CodePlex (Json.net), il peut être téléchargé depuis ce dernier ou même installé dans un projet via NuGet.

Mais toutes ces raisons ne sont pas suffisante pour embarquer une librairie de plus dans une application. Il faut bien entendu que les services rendus permettent des choses dont l’application a besoin et que les moteurs offerts par .NET ne puissent pas faire.

Voici un petit récapitulatif des différences entre les différents moteurs .NET (info données par JSON.NET) :

  Json.NET DataContractJsonSerializer JavaScriptSerializer
Supporte JSON Oui Oui Oui
Supporte BSON Oui Non Non
Supporte les schémas JSON Oui Non Non
Supporte .NET 2.0 Oui Non Non
Supporte .NET 3.5 Oui Oui Oui
Supporte .NET 4.0 Oui Oui Oui
Supporte .NET 4.5 Oui Oui Oui
Supporte Silverlight Oui Oui Non
Supporte Windows Phone Oui Oui Non
Supporte Windows 8 Oui Oui Non
Supporte Portable Class Library Oui Oui Non
Open Source Oui Non Non
Licence MIT Oui Non Non
LINQ to JSON Oui Non Non
Thread Safe Oui Oui Oui
Syntaxe JSON XPath-like Oui Non Non
Support JSON Indenté Oui Non Non
Sérialisation efficace des dictionnaires Oui Non Oui
Sérialization des dictionnaires "nonsensical" Non Oui Non
Déserialise les propriétés IList, IEnumerable, ICollection, IDictionary Oui Non Non
Serialise les références circulaires Oui Non Non
Supporte sérialisation par référence Oui Non Non
Déserialise propriétés et collection polymorphiques Oui Oui Oui
Sérialise et déserialise les arrays multidimentionelles Oui Non Non
Supporte inclusion des noms de type Oui Oui Oui
Personalisation globale du process de sérialisation Oui Oui Non
Supporte l'exclusion des null en sérialisation Oui Non Non
Supporte SerializationBinder Oui Non Non
Sérialisation conditionnelle Oui Non Non
Numéro de ligne dans les erreurs Oui Oui Non
Conversion XML à JSON et JSON à XML Oui Non Non
Validation de schéma JSON Oui Non Non
Génération de schéma JSON pour les types .NET Oui Non Non
Nom de propriétés en Camel case Oui Non Non
Supporte les constructeurs hors celui par défaut Oui Non Non
Gestion des erreurs de sérialisations Oui Non Non
Supporte la mise à jour d'un objet existant Oui Non Non
Sérialisation efficace des arrays en Base64 Oui Non Non
Gère les NaN, Infinity, -Infinity et undefined Oui Non Non
Gère les constructeurs JavaScript Oui Non Non
Sérialise les objets dynamiques .NET 4.0 Oui Non Non
Sérializes les objets ISerializable Oui Non Non
Supporte la sérialisation des enum par leur valeur texte Oui Non Non
Supporte la limite de récursion JSON Oui Oui Oui
Personnalisation des noms de propriétés par Attribut Oui Oui Non
Personnalisation de l'ordre des propriétés par Attribut Oui Oui Non
Personnalisation des propriétés "required" par Attribut Oui Oui Non
Supporte les dates ISO8601 Oui Non Non
Supporte le constructeur de data JavaScript Oui Non Non
Supporte les dates MS AJAX Oui Oui Oui
Supporte les noms sans quote Oui Non Non
Supporte JSON en mode "raw" Oui Non Non
Supporte les commentaires (lecture/écriture) Oui Non Non
Sérialise les type anonymes Oui Non Oui
Déserialise les types anonymes Oui Non Non
Sérialisation en mode Opt-in Oui Oui Non
Sérialisation en mode Opt-out Oui Non Oui
Sérialisation en mode champ Oui Oui Non
Lecture/écriture efficace des streams JSON Oui Oui Non
Contenu JSON avec simple ou double quote Oui Non Non
Surcharge de la sérialisation d'un type Oui Non Oui
Supporte OnDeserialized, OnSerializing, OnSerialized et OnDeserializing Oui Oui Non
Supporte la sérialisation des champs privés Oui Oui Non
Supporte l'attribut DataMember Oui Oui Non
Supporte l'attribut MetdataType Oui Non Non
Supporte l'attribut DefaultValue Oui Non Non
Sérialise les DataSets et DataTables Oui Non Non
Sérialise Entity Framework Oui Non Non
Sérialise nHibernate Oui Non Non
Désérialisation case-insensitive sur noms des propriétés Oui Non Non
Trace Oui Oui Non

 

Utiliser JSON.NET

Cette librairie est bien entendu documentée et son adoption assez large faitr qu’on trouve facilement des exemples sur Internet, je ne vais pas copier ici toutes ces informations auxquelles je renvoie le lecteur intéressé.

Juste pour l’exemple, un objet peut se sérialisé aussi simplement que cela :

var JSON = JsonConvert.SerializeObject( monObjet );

(le résultat JSON est une string)

La désérialisation n’est pas plus compliquée.

Ensuite on entre dans les méandres des attributs de personnalisation (changer le nom d’une propriété, imposer un ordre particulier, …) voire la surcharge complète du processus de sérialisation, tout cela peut emmener loin dans les arcanes de JSON.NET car la librairie supporte un haut degré de personnalisation justement.

Conclusion

La sérialisation tout le monde connaît et s’en sert soit épisodiquement, soit fréquemment, mais souvent sans trop se poser de questions.

En vous proposant de regarder de plus près JSON.NET c’est une réflexion plus vaste que j’espère susciter : une interrogation sur les besoins réels de vos applications en ce domaine et la prise de conscience que le moteur de sérialisation ne se choisit pas au hasard en prenant le premier qui est disponible…


   “MotDeLaFin”: “Stay Tuned!”
}

Faites des heureux, partagez l'article !
blog comments powered by Disqus