1. Giriş
Uzun müddət .NET ekosistemində JSON ilə işləmək üçün əsas vasitə möhtəşəm üçüncü tərəf paket Newtonsoft.Json (başqa adı ilə Json.NET) idi. O güclüdür, çevikdir və hələ də geniş istifadə olunur. Amma .NET 9 və C# 14-ün gəlməsi ilə Microsoft öz yüksəkperformanslı daxili JSON-serializatoruna sahib olmaq qərarına gəldi. Belə yaranıb System.Text.Json.
Niyə yeni yanaşma lazımdır? System.Text.Json müasir reallıqlar nəzərə alınaraq hazırlanıb və illər ərzində üçüncü tərəf kitabxanalarından istifadə zamanı yığılan problemləri həll edir. O maksimum sürət və təhlükəsizlik üçün optimallaşdırılıb, asynchronous ssenarilərə və web-API-lərə ideal uyğun gəlir və — ən xoş cəhət — NuGet-dən yükləmək lazım deyil: hamısı platformada var.
Əlbəttə, Newtonsoft.Json yoxa çıxmayıb və onu sonra da nəzərdən keçirəcəyik. Amma əksər yeni layihələr üçün System.Text.Json defolt seçimdir. Hazır olun — indi obyektlərimizi JSON-dilində danışdırmağı öyrənəcəyik!
2. System.Text.Json-la işləmənin əsasları
Obyektin sadə serializasiyası
Başlayaq əsas sehrdən. Obyektimizi JSON-sətirə serializasiya edək.
using System;
using System.Text.Json; // Unutmayın əlavə edin!
public class Player
{
public string Name { get; set; }
public int Health { get; set; }
public bool IsAlive { get; set; }
}
// Proqramınızın harasındasa:
Player player = new Player { Name = "Aragorn", Health = 100, IsAlive = true };
// Serializasiya:
string json = JsonSerializer.Serialize(player);
Console.WriteLine(json); // Çap edəcək: {"Name":"Aragorn","Health":100,"IsAlive":true}
Şərh: Əgər serializasiyanı yeni öyrənirsinizsə, bu nümunə göstərir ki, hər şey nə qədər sadədir: JsonSerializer.Serialize — və iş bitdi.
Obyektin deserializasiyası
JSON-sətirdən obyektimizi dirildirək:
string incomingJson = "{\"Name\":\"Legolas\",\"Health\":88,\"IsAlive\":true}";
Player player2 = JsonSerializer.Deserialize<Player>(incomingJson);
Console.WriteLine(player2.Name); // Legolas
Console.WriteLine(player2.Health); // 88
Console.WriteLine(player2.IsAlive); // true
Şərh: Əgər JSON strukturu sinifinizlə uyğun gəlirsə — hər şey problemsiz işləyir. Əks halda istisnalar və ya defolt dəyərlər mümkün ola bilər.
3. Serializasiyanın prinsipləri və işi
Uyğunlaşma necə baş verir
System.Text.Json defolt üzrə sinifdəki property adlarından istifadə edir. Case həssasdır! Əgər JSON-da health yazılıbsa, Health əvəzinə deserializasiya işə düşməyəcək — property defolt dəyərində qalacaq (0, false və ya null).
Məsələn:
// Kiçik hərflərlə açarlar olan JSON:
string badJson = "{\"name\":\"Gimli\",\"health\":120,\"isAlive\":true}";
Player player3 = JsonSerializer.Deserialize<Player>(badJson);
Console.WriteLine(player3.Name); // boş
Console.WriteLine(player3.Health); // 0
Console.WriteLine(player3.IsAlive); // false
Maraqlı fakt: Bir çox API açarları camelCase-də yazır, amma C#-da adətən PascalCase istifadə olunur. Bu problemi aşağıdakı ayarlarla həll etmək olar.
4. Serializasiyanın idarə edilməsi — options və ayarlar
JSON formatlaşdırma: "insan-oxunan" çıxış
Bəzən kompakt yox, gözəl formatlanmış JSON istəyirsiz — konfiq və ya log üçün.
var options = new JsonSerializerOptions
{
WriteIndented = true // İndent əlavə et
};
string prettyJson = JsonSerializer.Serialize(player, options);
Console.WriteLine(prettyJson);
/*
{
"Name": "Frodo",
"Health": 50,
"IsAlive": true,
"Inventory": [
"Ring",
"Bread",
"Torch"
],
"Position": {
"X": 5,
"Y": 15
}
}
*/
WriteIndented xüsusiyyəti aktivləşir və serializator girintilər və yeni sətrlər əlavə edir.
Ad üslubunun idarəsi (CamelCase vs PascalCase)
Əgər web-API ilə işləyirsinizsə və bütün açarlar camelCase-dirsə, ad siyasətini qoşun:
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
string camelCaseJson = JsonSerializer.Serialize(player, options);
// {"name":"Frodo","health":50,"isAlive":true,"inventory":["Ring","Bread","Torch"],"position":{"x":5,"y":15}}
Beləliklə deserializasiya zamanı da bu açarlar düzgün uyğunlaşdırılacaq:
string apiJson = "{\"name\":\"Bilbo\",\"health\":40,\"isAlive\":true,\"inventory\":[\"Mug\"],\"position\":{\"x\":10,\"y\":5}}";
Player bilbo = JsonSerializer.Deserialize<Player>(apiJson, options);
Console.WriteLine(bilbo.Name); // Bilbo
5. Faydalı nüanslar
[JsonIgnore] atributundan istifadə
Bəzən bütün property-ləri serializasiya etmək istəməzsiniz — məsələn, həssas məlumatlar və ya müvəqqəti hesablanmış dəyərlər.
using System.Text.Json.Serialization;
public class Player
{
public string Name { get; set; }
public int Health { get; set; }
[JsonIgnore] // Bu property JSON-a düşməyəcək
public bool IsSecretCharacter { get; set; }
}
İndi serializasiyada:
var player = new Player { Name = "Boromir", Health = 80, IsSecretCharacter = true };
string json = JsonSerializer.Serialize(player);
Console.WriteLine(json); // {"Name":"Boromir","Health":80}
Əks deserializasiyada IsSecretCharacter defolt dəyərini (false) alacaq.
[JsonPropertyName("...")]-dan istifadə
Tutaq ki, kodda property IsAlive adlanır, amma JSON-da "status" olmalıdır:
using System.Text.Json.Serialization;
public class Player
{
public string Name { get; set; }
public int Health { get; set; }
[JsonPropertyName("status")]
public bool IsAlive { get; set; }
}
Serializasiya indi belə görünəcək:
var player = new Player { Name = "Pippin", Health = 60, IsAlive = false };
string json = JsonSerializer.Serialize(player);
Console.WriteLine(json); // {"Name":"Pippin","Health":60,"status":false}
Və deserializasiya zamanı "status" açarı düzgün şəkildə IsAlive-ı dolduracaq.
Quraşdırılmış məhdudiyyətlər və təhlükəsizlik xüsusiyyətləri
- Defolt üzrə yalnız public get/set olan property-lər serializasiya olunur; private fieldlər/property-lər nəzərə alınmır.
- Dairəvi referanslar olduqda istisna atılır: "A possible object cycle was detected".
- Newtonsoft.Json-dan fərqli olaraq, standart serializator tiplərlə bağlı "sehrli" üsullara daha az müraciət edir — amma bu onu tipik ssenarilər üçün daha təhlükəsiz və sürətli edir.
6. Tez-tez rastlanan səhvlər və tələfələr
JSON-da property adını təsadüfən dəyişdirdiniz və kodu yeniləməyi unutdunuz — nəticədə property defolt dəyər alır (null, 0, false).
JSON-da lazımi sahə yoxdursa — uyğun property obyektində defolt olacaq (bax: sənədləşmə).
Property-nin public setteri yoxdursa — deserializasiya zamanı o doldurulmayacaq.
Daxili siniflərdə və ya kolleksiyalarda struktur dəyişikliyi etmisinizsə — deserializasiya qırıla və ya gözlənilməz nəticə verə bilər.
Eyni adın müxtəlif nesting səviyyələrində (parent və child obyektində) olması çaşdırıcı ola və debug-u çətinləşdirə bilər.
Bəzən problem platforma versiyası ilə bağlı olur: System.Text.Json-un köhnə versiyaları bəzi tiplərlə (Dictionary, DateTime, enum) yaxşı işləmirdi, amma .NET 7/8/9-da çox şey düzəldilib.
GO TO FULL VERSION