1. Giriş
Əgər siz .NET-də serialization ilə yeni tanış olursunuzsa, belə sual ortaya çıxa bilər: artıq daxili System.Text.Json varsa, başqa kitabxanaya niyə ehtiyac var? Cavab sadədir: Newtonsoft.Json əvvəllər yaranıb və illər ərzində hələ də JSON üçün .NET-də ən çevik alətə çevrilib.
O faktiki standart oldu, çünki mürəkkəb ssenariləri dəstəkləyir: custom contracts, güclü converters, private sahələrin serialization-u, LINQ to JSON, dinamik obyektlər (JObject), dövri istinadların elastik emalı və tarix/saat üçün çoxlu formatlar. Bir çox kitabxana və API hələ də Json.NET-i “kapotun altında” istifadə edir.
Vacib: bəzi ssenarilərdə daxili System.Text.Json hələ də Newtonsoft.Json-un imkanlarına çatmır, ona görə Json.NET-i öyrənmək aktualdır.
Newtonsoft.Json (Json.NET) necə əlavə etmək olar
Paketi NuGet vasitəsilə quraşdırın:
dotnet add package Newtonsoft.Json
Namespace-i daxil edin:
using Newtonsoft.Json;
2. Newtonsoft.Json ilə serialization
Gəlin ənənəvi Person sinifini götürək:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Obyekti JSON sətrinə serialize etmək
Person person = new Person { Name = "İvan", Age = 30 };
// JSON-a serialization
string json = JsonConvert.SerializeObject(person);
Console.WriteLine(json);
// Çıxış: {"Name":"İvan","Age":30}
JSON-u obyektə deserialize etmək
string json = "{\"Name\":\"İvan\",\"Age\":30}";
Person person = JsonConvert.DeserializeObject<Person>(json);
Console.WriteLine($"{person.Name}, {person.Age}");
// Çıxış: İvan, 30
"Kapotun altında" nə baş verir?
Newtonsoft.Json bütün public properties üzərində gəzir, onları JSON-a serialize edir və sətirə yazır. Deserialize edərkən JSON-dakı açarları property adları ilə uyğunlaşdırır və obyekti doldurur.
3. Obyekt kolleksiyalarının serialization-u
Kolleksiyaların və massivlərin serialization-u
Kolleksiyalar "out of the box" işləyir.
List<Person> people = new List<Person>
{
new Person { Name = "İvan", Age = 30 },
new Person { Name = "Mariya", Age = 25 }
};
string json = JsonConvert.SerializeObject(people);
// Çıxış: [{"Name":"İvan","Age":30},{"Name":"Mariya","Age":25}]
List<Person> deserialized = JsonConvert.DeserializeObject<List<Person>>(json);
// İndi yenə də sizdə Person siyahısı var!
Lüğətlərin (dictionary) serialization-u və deserialize-u xüsusiyyətləri
var dict = new Dictionary<string, int>
{
["apple"] = 2,
["banana"] = 5
};
string json = JsonConvert.SerializeObject(dict);
// Çıxış: {"apple":2,"banana":5}
var deserializedDict = JsonConvert.DeserializeObject<Dictionary<string,int>>(json);
// Hər şey işləyir!
Əgər açarlar string deyilsə (məsələn, Dictionary<int,string>), Json.NET serializasiya zamanı açarları string-ə çevirir və deserialize zamanı geri çevirməyə çalışır. Mürəkkəb açarlar üçün (məsələn, Guid) daha etibarlı üsul Dictionary<string, TValue> istifadə etməkdir.
4. Daxili obyektlər və iyerarxiyalarla iş
public class Order
{
public int Id { get; set; }
public Person Customer { get; set; }
public List<Product> Products { get; set; }
}
public class Product
{
public string Title { get; set; }
public double Price { get; set; }
}
Order order = new Order
{
Id = 123,
Customer = new Person { Name = "İvan", Age = 30 },
Products = new List<Product>
{
new Product { Title = "Noutbuk", Price = 50000.0 },
new Product { Title = "Maus", Price = 1500.0 }
}
};
string json = JsonConvert.SerializeObject(order);
Console.WriteLine(json);
Nəticə: daxil olan obyektlər JSON strukturunun içində düzgün şəkildə təmsil olunacaq.
5. Attributlar vasitəsilə serialization-un tənzimlənməsi
Property-ni ignore etmək
public class Person
{
public string Name { get; set; }
[JsonIgnore]
public int Age { get; set; }
}
İndi Age JSON-a düşməyəcək.
Property-ni adını dəyişmək
public class Person
{
[JsonProperty("full_name")]
public string Name { get; set; }
}
JSON-da ad "full_name" olacaq.
6. Elastik tənzimləmə: JsonSerializerSettings
Formatlaşdırma (oxunaqlı, çoxsətirli JSON):
string json = JsonConvert.SerializeObject(
people,
Formatting.Indented
);
Nəticə:
[
{
"Name": "İvan",
"Age": 30
},
{
"Name": "Mariya",
"Age": 25
}
]
Tez istifadə olunan tənzimləmələr:
| Xüsusiyyət | Təsvir |
|---|---|
|
null-properties necə emal etmək (onları ötürmək yoxsa açıq-aşkar null yazmaq) |
|
default dəyərləri ötürmək lazım olub-olmaması |
|
Dövri istinadlarla nə etmək lazımdır |
|
Tarix və saat üçün string formatları |
Null-u ötürən nümunə:
string json = JsonConvert.SerializeObject(
person,
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }
);
7. Dinamik JSON strukturları ilə iş: JObject, JArray və s.
Əgər JSON strukturu əvvəldən məlum deyilsə, Newtonsoft.Json.Linq-dən tiplərdən istifadə edin:
using Newtonsoft.Json.Linq;
string json = @"{
'Name': 'İvan',
'Age': 30,
'Skills': ['C#', 'SQL', 'JSON']
}";
JObject obj = JObject.Parse(json);
Console.WriteLine(obj["Name"]); // İvan
Console.WriteLine(obj["Skills"][0]); // C#
JSON-u "uçuşda" yaratmaq:
var jObj = new JObject
{
["Status"] = "Success",
["Result"] = new JArray("item1", "item2", "item3")
};
Console.WriteLine(jObj.ToString(Formatting.Indented));
JObject və JArray — JSON-obyekt və massivinin təmsilçiləridir, əslində rahat kolleksiyalardır.
8. Faydalı incəliklər
Dövri istinadlar
Newtonsoft.Json onları elastik şəkildə emal edə bilir:
var settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
string json = JsonConvert.SerializeObject(obj, settings);
Beləliklə dövrlər ötürüləcək. İstinadları saxlamaq üçün ReferenceLoopHandling.Serialize və [JsonObject(IsReference = true)] birlikdə istifadə etmək olar.
Anonim və dynamic obyektlərin serialization-u
var anon = new { Foo = 42, Bar = "Salam" };
string json = JsonConvert.SerializeObject(anon);
// {"Foo":42,"Bar":"Salam"}
Validation və səhvlərin emalı
try
{
Person p = JsonConvert.DeserializeObject<Person>(brokenJson);
}
catch (JsonSerializationException ex)
{
Console.WriteLine("Deserializasiya zamanı xəta: " + ex.Message);
}
Newtonsoft.Json vs System.Text.Json müqayisəsi
| Newtonsoft.Json (Json.NET) | System.Text.Json (.NET) | |
|---|---|---|
| NET dəstəyi | .NET Framework/Standard/6+ | .NET Core 3.0+ / .NET 5/6/9 |
| LINQ to JSON (JObject/JArray) | Bəli | Xeyr |
| Elastik tənzimləmə | Çox geniş | Məhdud |
| Attributlar ([JsonProperty], ...) | Bəli | Bəli (qismən, daha az imkan) |
| Private properties dəstəyi | Bəli | Xeyr |
| Sürət | Bəzi ssenarilərdə daha yavaş | Daha sürətli |
| Mürəkkəb converters | Bəli | Bəli (daha az çevik hələ) |
| DataTable, DataSet dəstəyi | Bəli | Xeyr |
| Sənədləşmə və nümunələr | Ləngər | Artmaqdadır |
9. Yeni başlayanların səhvləri və tipik tələlər
Səhv №1: Deserialize-dən sonra property-lər null olur.
Tez-tez property-də setter yoxdur və ya parametrsiz konstruktor mövcud deyil — serializerin obyekti doldurmaq üçün nə isə yox.
Səhv №2: JSON və sinif arasındakı property adlarının uyğunsuzluğu.
Əgər JSON-da sahə "fullName" və sinifdə — FullName varsa, [JsonProperty] istifadə edin və ya adların uyğunlaşdırılması üçün ContractResolver tənzimləyin.
Səhv №3: Serialization default olaraq yalnız public property-lərlə işləyir.
Private field/property-lər əlavə tənzimləmələr olmadan serialize edilmir. Converter-lər və ya xüsusi resolver/contract-lar lazım olur.
Səhv №4: Dövri istinadlar StackOverflowException-a gətirir.
Obyektlərin qarşılıqlı istinadları serialization-u siklaya bilər. İstinadların emalını tənzimləyin (məsələn, ReferenceLoopHandling) və ya data modelini dəyişdirin.
GO TO FULL VERSION