Archives Wild Code School
C#

Newtonsoft.JSONParser

Quête 43 sur 46

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 !

↗
Exemple de JSON

Comment GitHub rend disponible sur le réseau Internet les informations sur ses utilisateurs

api.github.com
↗
Explications sur JSON

Vidéo expliquant en moins de 10 minutes ce qu'est JSON

youtube.com
↗
Explications sur JSON

Vidéo expliquant JSON en une minute

youtube.com

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 :

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 :

json
{
    "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 :

json
"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:

cs
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érialisation avec Newtonsoft.Json

Sérialiser des collections

newtonsoft.com
↗
Sérialisation avec Newtonsoft.Json

Sérialiser des dates

newtonsoft.com

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:

cs
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:

  1. On déclare une chaîne de caractères représentant un objet JSON

  2. 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éthode DeserializeObject<T> va renvoyer un objet de type T et seuls les champs correspondants (par nom) de l'objet de type T seront mappés au JSON.

↗
Exemple de désérialisation

Documentation officielle de Newtonsoft.Json sur la désérialisation d'un objet JSON

newtonsoft.com
↗
Exemple de désérialisation

Documentation officielle de Newtonsoft.Json sur la désérialisation d'une collection JSON

newtonsoft.com

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:

cs
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.

↗
Exemple de sérialisation avec attributs

Documentation officielle de Newtonsoft sur la sérialisation avec attributs

newtonsoft.com

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 Wind ou Weather