Newtonsoft.JSONParser
Durant cette quête tu apprendras à te servir de la librairie JSONParser de Newtonsoft pour récupérer et traiter un fichier JSON simplement.
Parser un JSON avec JSONParser
Dans tous les langages, on dispose de structures telles que les tableaux et les objets. Quand on les manipule, il faut garder à l'esprit que celles-ci sont stockées dans la mémoire de travail de l'ordinateur.
Chaque langage a sa propre façon de stocker ces données. Pour communiquer ces données par réseau, il est nécessaire de disposer d'un moyen permettant de transformer ces données dans un format universel. Il existe plusieurs formats de communication "universels" ou "interopérables" : notamment XML et JSON.
Ces deux formats sont en réalité des données au format textuel (string), mais respectant une structure bien spécifique. C'est cette structure qui respecte une convention universelle.
Dans cette quête, tu vas d'abord voir comment un fichier JSON est structuré et ensuite, tu apprendras à l'analyser grâce à la bibliothèque Newtonsoft.JSONParser.
JSON ?
Le JSON (JavaScript Object Notation) est un format permettant de transcrire des données de façon textuelle. Ces données sont classées dans des objets sous forme d'arborescence :
-
une racine aura une clé (le nom de la donnée)
-
ses branches auront des clés et des valeurs (les propriétés de la donnée)
Regarde cette vidéo qui explique le JSON en 1:30 !
Pour voir à quoi ressemblent des données JSON réelles, ouvre cette page sur l'API de GitHub : https://api.github.com/users/defunkt. Ce sont les données publiques du compte d'un des cofondateurs de GitHub. Tu peux aussi remplacer le pseudo defunkt par le tien !
Comment GitHub rend disponible sur le réseau Internet les informations sur ses utilisateurs
Vidéo expliquant en moins de 10 minutes ce qu'est JSON
Vidéo expliquant JSON en une minute
Objets, tableaux et valeurs
Un fichier JSON est composé de deux types d'éléments : les JSON Objects et les JSON Array.
Voici à quoi ressemble un fichier JSON :
{
"name": "Eric Cartman",
"age": 10,
"size": 122.4,
"psychopath": true,
"contact": {
"name": "Liane Cartman",
"phone": "555-6754"
},
"hobbies": [
"World of Warcraft",
"Tacos",
"Drink tears"
],
"friends": null
}
1. Objet Json
Un objet JSON a la forme suivante :
{
"clé1": valeur1,
"clé2": valeur2
}
Un objet est représenté par des accolades : à une clé est associée une valeur.
2. Tableau Json
Un tableau JSON a la forme suivante :
"clé1": [
valeur1,
valeur2
]
Un tableau est représenté par des crochets: à une clé est associé un ensemble de valeurs.
3. Types de données JSON
Chaque valeur d'un objet JSON ou d'un tableau JSON peut faire partie de la liste suivante :
-
chaîne de caractères
-
nombre
-
booléen
-
Objet JSON
-
Tableau JSON
-
null
Librairies
Il existe plusieurs méthodes pour analyser des données contenues dans un fichier JSON en C#. Voici quelques bibliothèques permettant de le faire :
-
System.Text.Json - Développé par Microsoft, il est présent dans le framework .NET
-
Utf8Json - Auto-proclamé parseur le plus rapide, il n'écrit rien dans la mémoire vive
-
Newtonsoft.Json - Une librairie intuitive et simple d'utilisation, celle que nous utiliserons durant la quête
Installation de Newtonsoft.Json
Pour utiliser la librairie Newtonsoft.Json, il va falloir l'inclure comme dépendance au programme. La librairie n'étant pas présente nativement dans le framework .Net, il y a plusieurs façons de procéder à son installation.
1. NuGet
La plateforme https://www.nuget.org/ héberge une multitude de librairies différentes pour le framework .Net. D'autres alternatives existe, mais c'est la plus grande, la plus complète, et celle utilisée par défaut par Visual Studio.
NuGet est le gestionnaire de dépendance du framework .Net, comme bower est celui de Javascript, et maven/gradle ceux de Java.
En cherchant le nom de la librairie sur la page d'accueil, on accède à la page de Newtonsoft.Json : https://www.nuget.org/packages/Newtonsoft.Json/
Cette page présente la librairie, explique son utilité, donne les liens vers le repository Github du projet, etc... Elle propose également en haut de la page, plusieurs méthodes d'installation.
2. .NET Cli
En ouvrant un terminal quelconque dans le dossier de votre projet, et en rentrant la commande spécifiée (dotnet add package Newtonsoft.Json par exemple), la librairie sera ajoutée comme dépendance à ton projet. Lors de la compilation du projet, la librairie sera automatiquement téléchargée sur ton poste.
Il est possible de spécifier une version spécifique de la librairie lors de son installation, mais si ce n'est pas précisé, la dernière version sera utilisée automatiquement.
3. Package Manager
Si tu utilises Visual Studio, tu peux afficher une console particulière en faisant Affichage > Autre fenêtres > Console du Gestionnaire de package.
Cette console est particulière, et le prompt commence par PM>.
Sur la page nuget de la librairie, tu peux cliquer sur Package Manager en haut de la page.
La commande du style PM> Nuget\Install-Package Newtonsoft.Json est alors affichée. Tu peux la copier/coller (sans le PM>) dans la console de Visual Studio.
4. PackageReference
L'onglet PackageReference indique la ligne XML à ajouter dans ton fichier .csproj si tu n'as ni Visual Studio, ni console sur ton poste. Cette méthode étant moins pratique que les autres, nous n'allons pas nous étendre dessus.
5. Autres
Il existe d'autres onglets sur la page Nuget qui indique comment installer la librairie via des outils supplémentaires, mais nous n'en parlerons pas ici.
6. Intellisense
Pour certaines librairies bien connues (comme Newtonsoft.Json), Visual Studio pourra même te proposer d'installer la librairie automatiquement lorsque tu l'utilisera pour la première fois dans ton projet.
La classe utilisée est à ce moment là soulignée en rouge car il ne la reconnait pas, mais en utilisant la petite ampoule des suggestions, il est possible de demander l'installation de la librairie automatiquement.
7. Gestionnaire de paquet NuGet
Visual Studio propose également un outil graphique dédié à la gestion des librairies venant de Nuget. Pour l'afficher, il faut faire clic droit sur Dépendances dans l'explorateur de solution, puis Gérer les packages nuget.
On peut ainsi parcourir les librairies disponibles, gérer celles actuellement installées, et même vérifier la présence de mise à jour et les appliquer.
Il est donc possible de faire des recherches sur https://nuget.org directement depuis l'interface de Visual Studio.
Parsing
1.
Qu'est-ce que la sérialisation ?
La sérialisation est un procédé qui permet de transformer des objets (instances de classes) stockés en mémoire dans un programme et de les transformer dans un langage intermédiaire pour le partager avec d'autres programmes.
Newtonsoft.Json permet de facilement sérialiser un objet C# en objet JSON:
using Newtonsoft.Json;
namespace JsonTest
{
public static void Main()
{
Person p1 = new Person
{
FirstName = "Jean",
LastName = "Dupont",
Male = true,
BirthDate = new DateTime(1994, 8, 8, 0, 0, 0, DateTimeKind.Utc),
};
Person p2 = new Person
{
FirstName = "Jeanne",
LastName = "Dufour",
Male = false,
BirthDate = new DateTime(1994, 8, 8, 0, 0, 0, DateTimeKind.Utc),
};
List<Person> persons = new List<Person>();
persons.Add(p1);
persons.Add(p2);
string json = JsonConvert.SerializeObject(persons, Formatting.Indented);
// [
// {
// "FirstName": "Jean",
// "LastName": "Dupont",
// "Male": true,
// "BirthDate": "1994-08-08T00:00:00Z"
// },
// {
// "FirstName": "Jeanne",
// "LastName": "Dufour",
// "Male": false,
// "BirthDate": "1994-08-08T00:00:00Z"
// }
// ]
}
}
Ainsi, le code ci-dessus permet de transformer un objet Person C# en un objet JSON. Ce procédé permet de récupérer un object Person dans n'importe quel programme capable d'interpréter du JSON.
Sérialiser des collections
Sérialiser des dates
2.
Le processus inverse de la sérialisation s'appelle la désérialisation. Ce procédé permet de transformer un ou plusieurs objets exprimés dans un langage intermédiaire (JSON, XML et d'autres ...) en objets manipulables par un programme en tant qu'instance de classe avec ses propriétés et attibuts remplis par l'objet à désérialiser.
Désérialiser un objet JSON est très simple avec Newtonsoft.Json:
using Newtonsoft.Json;
using System;
namespace JsonDeserializingTest
{
public static void Main()
{
String jsonToDeserialize = @"{
'FirstName': 'Jean',
'LastName': 'Dupont',
'IsMale': true
}";
Person person = JsonConvert.DeserializeObject<Person>(jsonToDeserialize);
Console.WriteLine(person.FirstName); // Jean
}
public class Person
{
public String FirstName { get; set; }
public String LastName { get; set; }
public Boolean IsMale { get; set; }
}
}
Le code au-dessus mérite une petite explication:
-
On déclare une chaîne de caractères représentant un objet JSON
-
On désérialise l'objet en utilisant la méthode
DeserializeObject. Cette méthode a de spécial qu'elle est une méthode générique (une méthode à spécialiser pour un type de données en particulier). Ainsi, il suffit de spécifier le type entre les caractères<>pour que Newtonsoft.Json fasse correspondre les valeurs de l'objet JSON à l'objet C# par correspondance avec les noms de champs. Ainsi, l'appel de la méthodeDeserializeObject<T>va renvoyer un objet de typeTet seuls les champs correspondants (par nom) de l'objet de typeTseront mappés au JSON.
Documentation officielle de Newtonsoft.Json sur la désérialisation d'un objet JSON
Documentation officielle de Newtonsoft.Json sur la désérialisation d'une collection JSON
3.
Et si les noms de champs de l'objet sérialisé ne correspondent pas à l'objet désérialisé ?
Pas de panique, les développeurs de chez NewtonSoft ont pensé à ce cas tordu. Il est toujours possible de mapper manuellement les champs à des attributs/propriétés. Car oui, selon les standards de codage on peut avoir un nom de champ JSON écrit en snake_case et le nom de la propriété en C# en CamelCase.
Pour mapper un nom de champ d'un objet sérialisé n'ayant pas le même nom qu'un champ de l'objet désérialisé on utilise les attribut.
Voici un exemple:
using Newtonsoft.Json;
using System;
namespace JsonDeserializingWithAttributesTest
{
public static void Main()
{
String jsonToDeserialize = @"{
'first_name': 'Jean',
'last_name': 'Dupont',
'is_male': true
}";
Person person = JsonConvert.DeserializeObject<Person>(jsonToDeserialize);
Console.WriteLine(person.FirstName); // Jean
}
public class Person
{
[JsonProperty("first_name")]
public String FirstName { get; set; }
[JsonProperty("last_name")]
public String LastName { get; set; }
[JsonProperty("is_male")]
public Boolean IsMale { get; set; }
}
}
Le code ci-dessus fait correspondre les champs écrits en snake_case dans l'objet JSON aux champs en CamelCase de la classe définie en C#. La correspondance se fait grâce à l'attribut [JsonProperty("[nom champ]")] placé au-dessus de la déclaration des propriétés.
Les attributs ont beaucoup de pouvoir en Newtonsoft.Json, et je t'invite à consulter la documentation pour comprendre toutes les possibilités offertes par les-dits attributs.
Documentation officielle de Newtonsoft sur la sérialisation avec attributs
Challenge
Parser un fichier JSON de données météo
Télécharge ce fichier JSON.
Analyse-le pour en découvrir la structure puis déserialise l'objet JSON dans un objet capable de contenir les données du fichier JSON.
Critères de validation
-
Le noeud "wind" est converti en objet Wind
-
Le noeud "weather" est converti en objet Weather
-
Une classe WeatherInfo agrègre les classes Wind et Weather
-
La classe WeatherInfo contient toutes les autres informations ne rentrant pas dans la classe
WindouWeather