CodeGym /Corsi /C# SELF /Applicazione Newtonsoft.Js...

Applicazione Newtonsoft.Json

C# SELF
Livello 44 , Lezione 4
Disponibile

1. Introduzione

Newtonsoft.Json è una specie di dinosauro in senso buono. È stato lo standard de-facto per lavorare con JSON nell'ecosistema .NET per anni, molto prima che System.Text.Json emergesse. Milioni di progetti, migliaia di librerie e framework (anche molte parti di ASP.NET Core fino a poco tempo fa) hanno usato proprio Json.NET.

I suoi punti di forza sono:

  • Ricco di funzionalità e flessibile: Json.NET offre tantissime opzioni, attributi e modi per personalizzare la serializzazione e la deserializzazione. Sa fare cose che System.Text.Json fa con fatica o non fa proprio.
  • Tollerante verso JSON "non perfetto": i dati provenienti da sistemi esterni non sono sempre puliti — Json.NET è spesso più permissivo e permette di deserializzare con meno dolori.
  • Retrocompatibile: se un progetto o una libreria dipendono da Json.NET, saperlo usare rimane importante.

Certo, System.Text.Json è più veloce ed è pensato per i requisiti moderni. Ma Newtonsoft.Json resta uno strumento potente, soprattutto quando serve logica specifica o massima flessibilità.

Come installare Newtonsoft.Json?

Essendo una libreria esterna, aggiungi il package tramite NuGet:

  1. Apri il progetto.
  2. Clic destro sul progetto in Solution Explorer.
  3. Scegli "Manage NuGet Packages...".
  4. Nel campo di ricerca digita Newtonsoft.Json.
  5. Seleziona il package e premi "Install".

Dopo l'installazione avrai la nuova dipendenza — puoi usare Json.NET!

Confronto delle funzionalità di Newtonsoft.Json e System.Text.Json

Funzionalità System.Text.Json Newtonsoft.Json
Serializzazione/deserializzazione semplice
Supporto ad attributi per le proprietà Parziale Completo
Custom converters
Lavoro con campi privati No
Lavoro con strutture dinamiche Limitato
LINQ to JSON (JObject/JArray) No
Reference Loop Handling
Supporto DataTable, DataSet e tipi complessi No
Performance Migliore Buona

2. Esempio di serializzazione e deserializzazione di un oggetto semplice

Prendiamo una struttura di gioco comune, che evolveremo nelle lezioni:

public class Player
{
    public string Name { get; set; }
    public int Health { get; set; }
    public bool IsAlive { get; set; }
    public List<string> Inventory { get; set; }
    public Position Position { get; set; }
}

public class Position
{
    public int X { get; set; }
    public int Y { get; set; }
}

Ora salviamo l'oggetto Player in JSON e lo ripristiniamo:

using Newtonsoft.Json;

Player player1 = new Player
{
    Name = "Aragorn",
    Health = 100,
    IsAlive = true,
    Inventory = new List<string> { "sword", "bow", "healing potion" },
    Position = new Position { X = 10, Y = 25 }
};

// Serializzazione in stringa JSON
string json = JsonConvert.SerializeObject(player1, Formatting.Indented);
Console.WriteLine(json);

// Deserializzazione di nuovo in oggetto Player
Player player2 = JsonConvert.DeserializeObject<Player>(json);
Console.WriteLine($"Nome: {player2.Name}, salute: {player2.Health}");

Tutto? Quasi, ma questa è solo la punta dell'iceberg. Vediamo perché Newtonsoft.Json è più interessante e flessibile rispetto ad altre librerie.

3. Formattazione, impostazioni e opzioni avanzate

Quando serializzi un oggetto, puoi ottenere sia una stringa compatta sia un JSON formattato. Il comportamento è controllato da parametri e impostazioni.

Esempio: Differenti varianti di formattazione

// JSON leggibile
string prettyJson = JsonConvert.SerializeObject(player1, Formatting.Indented);

// JSON compatto "minificato"
string compactJson = JsonConvert.SerializeObject(player1, Formatting.None);

Impostazioni di serializzazione

Se serve, passa JsonSerializerSettings per un controllo fine:

var settings = new JsonSerializerSettings
{
    NullValueHandling = NullValueHandling.Ignore, // Saltare i campi con valore null
    DefaultValueHandling = DefaultValueHandling.Ignore, // Saltare i campi col valore di default
    Formatting = Formatting.Indented
};
string customJson = JsonConvert.SerializeObject(player1, settings);

Ottieni il massimo controllo sull'output: vuoi saltare i campi vuoti? fatto. Devi serializzare anche proprietà private? configura il contract.

4. Gestire campi e proprietà con attributi

Newtonsoft.Json supporta un sistema di attributi molto potente per personalizzare la serializzazione direttamente nelle classi.

JsonProperty — Rinominare le proprietà

Se il protocollo JSON richiede un nome diverso per un campo:

public class Player
{
    [JsonProperty("player_name")]
    public string Name { get; set; }
    // ...
}

JSON risultante:

{ "player_name": "Aragorn", ... }

JsonIgnore — Ignorare una proprietà

public class Player
{
    [JsonIgnore]
    public int Health { get; set; }
}

Ora il campo Health non comparirà nella serializzazione.

JsonConverter — Conversioni custom

Permette di specificare quale converter usare per un campo specifico.

public class Player
{
    [JsonConverter(typeof(InventoryToStringConverter))]
    public List<string> Inventory { get; set; }
}

(Dettagli sui converter — più avanti.)

5. Lavorare con oggetti annidati e collezioni

Json.NET gestisce bene oggetti annidati, array, collezioni e dizionari.

Esempio: Dizionari

public class GameStats
{
    public Dictionary<string, int> Scores { get; set; }
}

GameStats stats = new GameStats
{
    Scores = new Dictionary<string, int>
    {
        ["Alice"] = 1023,
        ["Bob"] = 999
    }
};

string statsJson = JsonConvert.SerializeObject(stats, Formatting.Indented);
Console.WriteLine(statsJson);

Il JSON sarà così:

{
  "Scores": {
    "Alice": 1023,
    "Bob": 999
  }
}

6. Strutture complesse: riferimenti ciclici, Self-Referencing Objects

A volte gli oggetti contengono riferimenti reciproci. Newtonsoft.Json supporta la serializzazione di queste strutture tramite impostazioni dedicate.

Esempio: Risolvere riferimenti ciclici

public class Person
{
    public string Name { get; set; }
    public Person Parent { get; set; }
    public List<Person> Children { get; set; }
}

// Configuriamo la serializzazione per i cicli
var settings = new JsonSerializerSettings
{
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore // oppure .Serialize
};

Person p1 = new Person { Name = "Papa" };
Person p2 = new Person { Name = "Figlio", Parent = p1 };
p1.Children = new List<Person> { p2 };

string json = JsonConvert.SerializeObject(p1, settings);
Console.WriteLine(json);

Di default, se lasci ReferenceLoopHandling = Error, otterrai un'eccezione. Questo protegge da serializzazioni infinite accidentali.

7. Lavorare con strutture dinamiche: JObject, JArray

Quando la struttura JSON è sconosciuta a priori o cambia dinamicamente, usa oggetti dinamici senza forte tipizzazione C#.

Tipi principali:

  • JObject — rappresentazione di un oggetto JSON.
  • JArray — rappresentazione di un array.
using Newtonsoft.Json.Linq;

// Convertire una stringa in JObject
string json = @"{ 'name': 'Aragorn', 'health': 100 }";
JObject obj = JObject.Parse(json);

Console.WriteLine((string)obj["name"]); // Aragorn
Console.WriteLine((int)obj["health"]);  // 100

// Aggiungere dinamicamente proprietà
obj["class"] = "Ranger";
Console.WriteLine(obj.ToString());

Iterare un array

string jsonArr = @"['apple', 'banana', 'cherry']";
JArray array = JArray.Parse(jsonArr);

foreach (JToken item in array)
{
    Console.WriteLine(item);
}

8. Supporto per versioning e campi obbligatori

Il formato JSON può cambiare, alcuni campi possono mancare. Usa attributi e impostazioni:

  • [JsonProperty(Required = Required.Always)] — richiede la presenza del campo (altrimenti eccezione).
  • [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] — inserisce il default se il campo manca.
public class Player
{
    [JsonProperty(Required = Required.Always)]
    public string Name { get; set; }

    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
    [DefaultValue(50)]
    public int Health { get; set; }
}

9. Conversione di date e formati temporali

Lavorare con le date spesso richiede un formato esplicito.

var dateSettings = new JsonSerializerSettings
{
    DateFormatString = "yyyy-MM-dd"
};
string json = JsonConvert.SerializeObject(DateTime.Now, dateSettings);
Console.WriteLine(json); // "2024-06-15"

E al contrario durante la deserializzazione:

string dateJson = "\"2024-06-15\""; // Attenzione: è una stringa tra virgolette!
DateTime dt = JsonConvert.DeserializeObject<DateTime>(dateJson);
Console.WriteLine(dt);
1
Sondaggio/quiz
Classi standard di serializzazione, livello 44, lezione 4
Non disponibile
Classi standard di serializzazione
Classi e librerie per la serializzazione
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION