JsonSerializer (System.Text.Json) în C# (.NET)

.NET BCL și CLI-ul dotnet .NET Core 3.0+ / .NET 5+ (inclus nativ în BCL)

Serializează obiecte C# în format JSON și deserializează text JSON înapoi în tipuri puternic tipizate, cu performanță nativă ridicată.

Sintaxă C#
string json = JsonSerializer.Serialize(obiect, optiuni); | T? obj = JsonSerializer.Deserialize<T>(json, optiuni);

Ce face JsonSerializer (System.Text.Json)

Clasa System.Text.Json.JsonSerializer este biblioteca de serializare JSON nativă, de înaltă performanță și cu alocări minime de memorie inclusă direct în .NET (înlocuind în proiectele noi biblioteca externă Newtonsoft.Json). Este utilizată implicit de ASP.NET Core pentru toate API-urile web.

Prin clasa de configurare JsonSerializerOptions (și presetarea JsonSerializerDefaults.Web), poți activa formatarea indentată (WriteIndented = true), conversia automată a numelor de proprietăți din PascalCase (convenția C#) în camelCase (convenția JSON/JavaScript) și citirea insensibilă la majuscule (PropertyNameCaseInsensitive = true). Pentru personalizări punctuale pe un model se folosesc atributele [JsonPropertyName("...")] și [JsonIgnore].

Parametri, metode și opțiuni

Parametru / Metodă Descriere
JsonSerializer.Serialize(val, options) Convertește un obiect C# într-un șir JSON.
JsonSerializer.Deserialize<T>(json, options) Parsează un șir JSON și construiește o instanță de tipul T (poate returna null dacă JSON-ul este "null").
new JsonSerializerOptions(JsonSerializerDefaults.Web) Configurează automat camelCase, PropertyNameCaseInsensitive = true și citirea numerelor din șiruri.
WriteIndented = true Formatează JSON-ul generat pe mai multe linii, cu indentare lizibilă.
[JsonPropertyName("nume_json")] Atribut aplicat pe o proprietate C# pentru a-i mapa explicit cheia din JSON.
[JsonIgnore] Exclude proprietatea de la serializare și deserializare (ideal pentru parole sau câmpuri interne).

Exemple

Exemplul 1: Serializare în camelCase indentat și control cu atributele [JsonPropertyName] și [JsonIgnore]

Reutilizăm o instanță static readonly JsonSerializerOptions (recomandare critică de performanță în .NET) pentru a serializa și deserializa un obiect record.

using System.Text.Json;
using System.Text.Json.Serialization;

var optiuni = new JsonSerializerOptions(JsonSerializerDefaults.Web)
{
    WriteIndented = true
};

var cont = new ContUtilizator(
    Id: 42,
    NumeComplet: "Elena Dumitru",
    HashParola: "sha256$secret",
    Roluri: ["admin", "editor"]
);

string json = JsonSerializer.Serialize(cont, optiuni);
Console.WriteLine("JSON generat:");
Console.WriteLine(json);

ContUtilizator? deserializat = JsonSerializer.Deserialize<ContUtilizator>(json, optiuni);
Console.WriteLine($"\nDeserializat: {deserializat?.NumeComplet} (roluri: {deserializat?.Roluri.Length})");

public record ContUtilizator(
    int Id,
    [property: JsonPropertyName("full_name")] string NumeComplet,
    [property: JsonIgnore] string HashParola,
    string[] Roluri
);

Ieșire în consolă

JSON generat:
{
  "id": 42,
  "full_name": "Elena Dumitru",
  "roluri": [
    "admin",
    "editor"
  ]
}

Deserializat: Elena Dumitru (roluri: 2)

Exemplul 2: Deserializarea unui JSON extern cu PropertyNameCaseInsensitive

În mod implicit, JsonSerializer.Deserialize este sensibil la majuscule: o cheie "pret": 150 din JSON nu se va mapa pe proprietatea C# Pret dacă nu activezi PropertyNameCaseInsensitive = true (sau profilul JsonSerializerDefaults.Web).

using System.Text.Json;

string jsonPrimit = """{"codProdus": "SKU-900", "pret": 299.99, "disponibil": true}""";

var optiuniWeb = new JsonSerializerOptions(JsonSerializerDefaults.Web);
StocDto? dto = JsonSerializer.Deserialize<StocDto>(jsonPrimit, optiuniWeb);

Console.WriteLine($"Produs: {dto?.CodProdus} | Preț: {dto?.Pret} RON | Disponibil: {dto?.Disponibil}");

public record StocDto(string CodProdus, decimal Pret, bool Disponibil);

Ieșire în consolă

Produs: SKU-900 | Preț: 299.99 RON | Disponibil: True

Greșeli frecvente

  • Apelarea JsonSerializer.Deserialize<Model>(json) fără opțiuni pe un JSON cu chei în camelCase ({"nume": "Ion"}) când clasa C# are proprietăți în PascalCase (public string Nume { get; set; }) — proprietățile vor rămâne null / 0! Pasează întotdeauna new JsonSerializerOptions(JsonSerializerDefaults.Web) sau PropertyNameCaseInsensitive = true.
  • Crearea unei instanțe noi new JsonSerializerOptions { ... } la fiecare apel în interiorul unei bucle sau metode apelate frecvent — cache-ul intern de metadate al serializatorului este legat de instanța JsonSerializerOptions, deci stocheaz-o într-un câmp private static readonly.

Funcții și concepte înrudite

  • HttpClient (GetFromJsonAsync): Trimite cereri HTTP asincrone către API-uri REST și deserializează direct răspunsurile JSON cu metodele din System.Net.Http.Json.
  • record și imutabilitate: Definește într-o singură linie modele de date imutabile cu egalitate bazată pe valoare, afișare automată și clonare nedistructivă (with).
  • File.ReadAllText / WriteAllTextAsync: Citește și scrie fișiere text sau linii pe disc (sincron și asincron) și construiește căi multi-platformă cu Path.Combine.