Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Artikel ini memperlihatkan cara menggunakan model objek dokumen JSON (DOM) untuk akses acak ke data dalam payload JSON.
Pilihan DOM JSON
Bekerja dengan DOM adalah alternatif untuk deserialisasi dengan JsonSerializer ketika:
- Anda tidak memiliki jenis untuk dideserialisasi.
- JSON yang Anda terima tidak memiliki skema tetap dan harus diperiksa untuk mengetahui isinya.
System.Text.Json menyediakan dua cara untuk membangun DOM JSON:
JsonDocument menyediakan kemampuan untuk membangun DOM baca-saja dengan menggunakan
Utf8JsonReader. Elemen JSON yang menyusun payload dapat diakses melalui jenis JsonElement. JenisJsonElementini menyediakan enumerator array dan objek bersama dengan API untuk mengonversi teks JSON ke jenis .NET umum.JsonDocumentmengekspos RootElement properti. Untuk informasi selengkapnya, lihat Menggunakan JsonDocument nanti di artikel ini.JsonNode dan kelas yang berasal darinya di namespace layanan System.Text.Json.Nodes memberikan kemampuan untuk membuat DOM yang dapat diubah. Elemen JSON yang menyusun payload dapat diakses melalui jenis JsonNode, JsonObject, JsonArray, JsonValue, dan JsonElement. Untuk informasi selengkapnya, lihat Gunakan
JsonNodenanti di artikel ini.
Pertimbangkan faktor-faktor berikut saat memilih antara JsonDocument dan JsonNode:
- DOM
JsonNodedapat diubah setelah dibuat. DOMJsonDocumenttidak dapat diubah. - DOM
JsonDocumentmenyediakan akses yang lebih cepat ke datanya.
Menggunakan JsonNode
Contoh berikut menunjukkan cara menggunakan JsonNode dan jenis lain di namespace layanan System.Text.Json.Nodes untuk:
- Membuat DOM dari string JSON
- Tulis JSON dari DOM.
- Dapatkan nilai, objek, atau array dari DOM.
using System.Text.Json;
using System.Text.Json.Nodes;
namespace JsonNodeFromStringExample;
public class Program
{
public static void Main()
{
string jsonString = """
{
"Date": "2019-08-01T00:00:00",
"Temperature": 25,
"Summary": "Hot",
"DatesAvailable": [
"2019-08-01T00:00:00",
"2019-08-02T00:00:00"
],
"TemperatureRanges": {
"Cold": {
"High": 20,
"Low": -10
},
"Hot": {
"High": 60,
"Low": 20
}
}
}
""";
// Create a JsonNode DOM from a JSON string.
JsonNode forecastNode = JsonNode.Parse(jsonString)!;
// Write JSON from a JsonNode
var options = new JsonSerializerOptions { WriteIndented = true };
Console.WriteLine(forecastNode!.ToJsonString(options));
// output:
//{
// "Date": "2019-08-01T00:00:00",
// "Temperature": 25,
// "Summary": "Hot",
// "DatesAvailable": [
// "2019-08-01T00:00:00",
// "2019-08-02T00:00:00"
// ],
// "TemperatureRanges": {
// "Cold": {
// "High": 20,
// "Low": -10
// },
// "Hot": {
// "High": 60,
// "Low": 20
// }
// }
//}
// Get value from a JsonNode.
JsonNode temperatureNode = forecastNode!["Temperature"]!;
Console.WriteLine($"Type={temperatureNode.GetType()}");
Console.WriteLine($"JSON={temperatureNode.ToJsonString()}");
//output:
//Type = System.Text.Json.Nodes.JsonValue`1[System.Text.Json.JsonElement]
//JSON = 25
// Get a typed value from a JsonNode.
int temperatureInt = (int)forecastNode!["Temperature"]!;
Console.WriteLine($"Value={temperatureInt}");
//output:
//Value=25
// Get a typed value from a JsonNode by using GetValue<T>.
temperatureInt = forecastNode!["Temperature"]!.GetValue<int>();
Console.WriteLine($"TemperatureInt={temperatureInt}");
//output:
//Value=25
// Get a JSON object from a JsonNode.
JsonNode temperatureRanges = forecastNode!["TemperatureRanges"]!;
Console.WriteLine($"Type={temperatureRanges.GetType()}");
Console.WriteLine($"JSON={temperatureRanges.ToJsonString()}");
//output:
//Type = System.Text.Json.Nodes.JsonObject
//JSON = { "Cold":{ "High":20,"Low":-10},"Hot":{ "High":60,"Low":20} }
// Get a JSON array from a JsonNode.
JsonNode datesAvailable = forecastNode!["DatesAvailable"]!;
Console.WriteLine($"Type={datesAvailable.GetType()}");
Console.WriteLine($"JSON={datesAvailable.ToJsonString()}");
//output:
//datesAvailable Type = System.Text.Json.Nodes.JsonArray
//datesAvailable JSON =["2019-08-01T00:00:00", "2019-08-02T00:00:00"]
// Get an array element value from a JsonArray.
JsonNode firstDateAvailable = datesAvailable[0]!;
Console.WriteLine($"Type={firstDateAvailable.GetType()}");
Console.WriteLine($"JSON={firstDateAvailable.ToJsonString()}");
//output:
//Type = System.Text.Json.Nodes.JsonValue`1[System.Text.Json.JsonElement]
//JSON = "2019-08-01T00:00:00"
// Get a typed value by chaining references.
int coldHighTemperature = (int)forecastNode["TemperatureRanges"]!["Cold"]!["High"]!;
Console.WriteLine($"TemperatureRanges.Cold.High={coldHighTemperature}");
//output:
//TemperatureRanges.Cold.High = 20
// Parse a JSON array
var datesNode = JsonNode.Parse(@"[""2019-08-01T00:00:00"",""2019-08-02T00:00:00""]");
JsonNode firstDate = datesNode![0]!.GetValue<DateTime>();
Console.WriteLine($"firstDate={ firstDate}");
//output:
//firstDate = "2019-08-01T00:00:00"
}
}
Membuat DOM JsonNode dengan penginisialisasi objek dan membuat perubahan
Contoh berikut menunjukkan cara membatalkan pekerjaan.
- Buat DOM dengan menggunakan penginisialisasi objek.
- Buat perubahan pada DOM.
using System.Text.Json;
using System.Text.Json.Nodes;
namespace JsonNodeFromObjectExample;
public class Program
{
public static void Main()
{
// Create a new JsonObject using object initializers.
var forecastObject = new JsonObject
{
["Date"] = new DateTime(2019, 8, 1),
["Temperature"] = 25,
["Summary"] = "Hot",
["DatesAvailable"] = new JsonArray(
new DateTime(2019, 8, 1), new DateTime(2019, 8, 2)),
["TemperatureRanges"] = new JsonObject
{
["Cold"] = new JsonObject
{
["High"] = 20,
["Low"] = -10
}
},
["SummaryWords"] = new JsonArray("Cool", "Windy", "Humid")
};
// Add an object.
forecastObject!["TemperatureRanges"]!["Hot"] =
new JsonObject { ["High"] = 60, ["Low"] = 20 };
// Remove a property.
forecastObject.Remove("SummaryWords");
// Change the value of a property.
forecastObject["Date"] = new DateTime(2019, 8, 3);
var options = new JsonSerializerOptions { WriteIndented = true };
Console.WriteLine(forecastObject.ToJsonString(options));
//output:
//{
// "Date": "2019-08-03T00:00:00",
// "Temperature": 25,
// "Summary": "Hot",
// "DatesAvailable": [
// "2019-08-01T00:00:00",
// "2019-08-02T00:00:00"
// ],
// "TemperatureRanges": {
// "Cold": {
// "High": 20,
// "Low": -10
// },
// "Hot": {
// "High": 60,
// "Low": 20
// }
// }
//}
}
}
Mendeserialisasi subbagian payload JSON
Contoh berikut menunjukkan cara menggunakan JsonNode untuk menavigasi ke subbagian pohon JSON dan mendeserialisasi satu nilai, jenis kustom, atau array dari subbagian tersebut.
using System.Text.Json;
using System.Text.Json.Nodes;
namespace JsonNodePOCOExample;
public class TemperatureRanges : Dictionary<string, HighLowTemps>
{
}
public class HighLowTemps
{
public int High { get; set; }
public int Low { get; set; }
}
public class Program
{
public static DateTime[]? DatesAvailable { get; set; }
public static void Main()
{
string jsonString = """
{
"Date": "2019-08-01T00:00:00",
"Temperature": 25,
"Summary": "Hot",
"DatesAvailable": [
"2019-08-01T00:00:00",
"2019-08-02T00:00:00"
],
"TemperatureRanges": {
"Cold": {
"High": 20,
"Low": -10
},
"Hot": {
"High": 60,
"Low": 20
}
}
}
""";
// Parse all of the JSON.
JsonNode forecastNode = JsonNode.Parse(jsonString)!;
// Get a single value
int hotHigh = forecastNode["TemperatureRanges"]!["Hot"]!["High"]!.GetValue<int>();
Console.WriteLine($"Hot.High={hotHigh}");
// output:
//Hot.High=60
// Get a subsection and deserialize it into a custom type.
JsonObject temperatureRangesObject = forecastNode!["TemperatureRanges"]!.AsObject();
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream);
temperatureRangesObject.WriteTo(writer);
writer.Flush();
TemperatureRanges? temperatureRanges =
JsonSerializer.Deserialize<TemperatureRanges>(stream.ToArray());
Console.WriteLine($"Cold.Low={temperatureRanges!["Cold"].Low}, Hot.High={temperatureRanges["Hot"].High}");
// output:
//Cold.Low=-10, Hot.High=60
// Get a subsection and deserialize it into an array.
JsonArray datesAvailable = forecastNode!["DatesAvailable"]!.AsArray()!;
Console.WriteLine($"DatesAvailable[0]={datesAvailable[0]}");
// output:
//DatesAvailable[0]=8/1/2019 12:00:00 AM
}
}
Contoh nilai rata-rata JsonNode
Contoh berikut memilih array JSON yang memiliki nilai bilangan bulat dan menghitung nilai rata-rata:
using System.Text.Json.Nodes;
namespace JsonNodeAverageGradeExample;
public class Program
{
public static void Main()
{
string jsonString = """
{
"Class Name": "Science",
"Teacher\u0027s Name": "Jane",
"Semester": "2019-01-01",
"Students": [
{
"Name": "John",
"Grade": 94.3
},
{
"Name": "James",
"Grade": 81.0
},
{
"Name": "Julia",
"Grade": 91.9
},
{
"Name": "Jessica",
"Grade": 72.4
},
{
"Name": "Johnathan"
}
],
"Final": true
}
""";
double sum = 0;
JsonNode document = JsonNode.Parse(jsonString)!;
JsonArray studentsArray = document["Students"]!.AsArray();
int count = studentsArray.Count;
foreach (JsonNode? student in studentsArray)
{
if (student?["Grade"] is JsonNode gradeNode)
{
sum += (double)gradeNode;
}
else
{
sum += 70;
}
}
double average = sum / count;
Console.WriteLine($"Average grade : {average}");
}
}
// output:
//Average grade : 81.92
Kode sebelumnya:
- Menghitung nilai rata-rata untuk objek dalam
Studentsarray yang memiliki propertiGrade. - Menetapkan nilai default 70 untuk siswa yang tidak memiliki nilai.
- Mendapatkan jumlah siswa dari properti
CountpadaJsonArray.
JsonNodedenganJsonSerializerOptions
Anda dapat menggunakan JsonSerializer untuk menserialisasikan dan mendeserialisasi instans JsonNode. Namun, jika Anda menggunakan overload yang membutuhkan JsonSerializerOptions, instans opsi hanya digunakan untuk mendapatkan pengonversi kustom. Fitur lain dari instans opsi tidak digunakan. Misalnya, jika Anda menyetel JsonSerializerOptions.DefaultIgnoreCondition ke WhenWritingNull dan memanggil JsonSerializer dengan overload yang membutuhkan JsonSerializerOptions, properti null tidak akan diabaikan.
Batasan yang sama berlaku untuk metode JsonNode yang menggunakan parameter JsonSerializerOptions: WriteTo(Utf8JsonWriter, JsonSerializerOptions) dan ToJsonString(JsonSerializerOptions). API ini hanya menggunakan JsonSerializerOptions untuk mendapatkan pengonversi kustom.
Contoh berikut mengilustrasikan hasil penggunaan metode yang mengambil parameter JsonSerializerOptions dan membuat serial instans JsonNode:
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace JsonNodeWithJsonSerializerOptions;
public class Program
{
public static void Main()
{
Person person = new() { Name = "Nancy" };
// Default serialization - Address property included with null token.
// Output: {"Name":"Nancy","Address":null}
string personJsonWithNull = JsonSerializer.Serialize(person);
Console.WriteLine(personJsonWithNull);
// Serialize and ignore null properties - null Address property is omitted
// Output: {"Name":"Nancy"}
JsonSerializerOptions options = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
string personJsonWithoutNull = JsonSerializer.Serialize(person, options);
Console.WriteLine(personJsonWithoutNull);
// Ignore null properties doesn't work when serializing JsonNode instance
// by using JsonSerializer.
// Output: {"Name":"Nancy","Address":null}
JsonNode? personJsonNode = JsonSerializer.Deserialize<JsonNode>(personJsonWithNull);
personJsonWithNull = JsonSerializer.Serialize(personJsonNode, options);
Console.WriteLine(personJsonWithNull);
// Ignore null properties doesn't work when serializing JsonNode instance
// by using JsonNode.ToJsonString method.
// Output: {"Name":"Nancy","Address":null}
personJsonWithNull = personJsonNode!.ToJsonString(options);
Console.WriteLine(personJsonWithNull);
// Ignore null properties doesn't work when serializing JsonNode instance
// by using JsonNode.WriteTo method.
// Output: {"Name":"Nancy","Address":null}
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream);
personJsonNode!.WriteTo(writer, options);
writer.Flush();
personJsonWithNull = Encoding.UTF8.GetString(stream.ToArray());
Console.WriteLine(personJsonWithNull);
}
}
public class Person
{
public string? Name { get; set; }
public string? Address { get; set; }
}
Jika Anda memerlukan fitur JsonSerializerOptions selain pengonversi khusus, gunakan JsonSerializer dengan target yang diketik dengan kuat (seperti kelas Person dalam contoh ini) daripada JsonNode.
Memanipulasi pesanan properti
JsonObject adalah salah satu elemen dalam payload JsonNode, dan mewakili objek JSON yang dapat diubah. Meskipun jenisnya dimodelkan sebagai IDictionary<string, JsonNode>, di mana setiap entri adalah properti objek, jenis ini merangkum urutan properti implisit. Namun, API seperti Insert(Int32, String, JsonNode) dan RemoveAt(Int32) secara efektif memodelkan jenis sebagai kamus yang diurutkan dengan memungkinkan Anda menyisipkan dan menghapus item pada indeks tertentu. API ini memungkinkan modifikasi pada instans objek yang dapat secara langsung memengaruhi urutan properti.
Kode berikut menunjukkan contoh menambahkan atau memindahkan properti tertentu ke awal objek.
var schema = (JsonObject)JsonSerializerOptions.Default.GetJsonSchemaAsNode(typeof(MyPoco));
JsonNode? idValue;
switch (schema.IndexOf("$id"))
{
// $id property missing.
case < 0:
idValue = (JsonNode)"https://example.com/schema";
schema.Insert(0, "$id", idValue);
break;
// $id property already at the start of the object.
case 0:
break;
// $id exists but not at the start of the object.
case int index:
idValue = schema[index];
schema.RemoveAt(index);
schema.Insert(0, "$id", idValue);
break;
}
Membandingkan JsonNodes
Untuk membandingkan dua JsonNode objek untuk kesetaraan, termasuk elemen turunannya, gunakan metode .JsonNode.DeepEquals(JsonNode, JsonNode)
Menggunakan JsonDocument
Contoh berikut menunjukkan cara menggunakan kelas JsonDocument untuk akses acak ke data dalam string JSON:
double sum = 0;
int count = 0;
using (JsonDocument document = JsonDocument.Parse(jsonString))
{
JsonElement root = document.RootElement;
JsonElement studentsElement = root.GetProperty("Students");
foreach (JsonElement student in studentsElement.EnumerateArray())
{
if (student.TryGetProperty("Grade", out JsonElement gradeElement))
{
sum += gradeElement.GetDouble();
}
else
{
sum += 70;
}
count++;
}
}
double average = sum / count;
Console.WriteLine($"Average grade : {average}");
Dim sum As Double = 0
Dim count As Integer = 0
Using document As JsonDocument = JsonDocument.Parse(jsonString)
Dim root As JsonElement = document.RootElement
Dim studentsElement As JsonElement = root.GetProperty("Students")
For Each student As JsonElement In studentsElement.EnumerateArray()
Dim gradeElement As JsonElement = Nothing
If student.TryGetProperty("Grade", gradeElement) Then
sum += gradeElement.GetDouble()
Else
sum += 70
End If
count += 1
Next
End Using
Dim average As Double = sum / count
Console.WriteLine($"Average grade : {average}")
Kode sebelumnya:
- Mengasumsikan JSON yang akan dianalisis berada dalam string bernama
jsonString. - Menghitung nilai rata-rata untuk objek dalam
Studentsarray yang memiliki propertiGrade. - Menetapkan nilai default 70 untuk siswa yang tidak memiliki nilai.
- Membuat instans
JsonDocumentdalamusingpernyataan karenaJsonDocumentmengimplementasikanIDisposable. Setelah instansJsonDocumentdibuang, Anda juga kehilangan akses ke semua instansJsonElement. Untuk mempertahankan akses ke instansJsonElement, buat salinannya sebelum instansJsonDocumentinduk dibuang. Untuk membuat salinan, hubungi JsonElement.Clone. Untuk informasi selengkapnya, lihat JsonDocument adalah IDisposable.
Contoh kode sebelumnya menghitung siswa dengan menaikkan variabel count dengan setiap perulangan. Alternatifnya adalah memanggil GetArrayLength, seperti yang ditunjukkan dalam contoh berikut:
double sum = 0;
int count = 0;
using (JsonDocument document = JsonDocument.Parse(jsonString))
{
JsonElement root = document.RootElement;
JsonElement studentsElement = root.GetProperty("Students");
count = studentsElement.GetArrayLength();
foreach (JsonElement student in studentsElement.EnumerateArray())
{
if (student.TryGetProperty("Grade", out JsonElement gradeElement))
{
sum += gradeElement.GetDouble();
}
else
{
sum += 70;
}
}
}
double average = sum / count;
Console.WriteLine($"Average grade : {average}");
Dim sum As Double = 0
Dim count As Integer = 0
Using document As JsonDocument = JsonDocument.Parse(jsonString)
Dim root As JsonElement = document.RootElement
Dim studentsElement As JsonElement = root.GetProperty("Students")
count = studentsElement.GetArrayLength()
For Each student As JsonElement In studentsElement.EnumerateArray()
Dim gradeElement As JsonElement = Nothing
If student.TryGetProperty("Grade", gradeElement) Then
sum += gradeElement.GetDouble()
Else
sum += 70
End If
Next
End Using
Dim average As Double = sum / count
Console.WriteLine($"Average grade : {average}")
Berikut adalah contoh JSON yang diproses kode ini:
{
"Class Name": "Science",
"Teacher\u0027s Name": "Jane",
"Semester": "2019-01-01",
"Students": [
{
"Name": "John",
"Grade": 94.3
},
{
"Name": "James",
"Grade": 81.0
},
{
"Name": "Julia",
"Grade": 91.9
},
{
"Name": "Jessica",
"Grade": 72.4
},
{
"Name": "Johnathan"
}
],
"Final": true
}
Untuk contoh serupa yang menggunakan JsonNode dan bukan JsonDocument, lihat contoh nilai rata-rata JsonNode.
Cara mencari JsonDocument dan JsonElement untuk subelemen
Pencarian pada JsonElement memerlukan pencarian berurutan dari properti dan karenanya relatif lambat (misalnya saat menggunakan TryGetProperty). System.Text.Json dirancang untuk meminimalkan waktu penguraian awal daripada waktu pencarian. Oleh karena itu, gunakan pendekatan berikut untuk mengoptimalkan performa saat mencari melalui objek JsonDocument:
- Gunakan enumerator bawaan (EnumerateArray dan EnumerateObject) dibanding melakukan pengindeksan atau perulangan Anda sendiri.
- Jangan melakukan penelusuran berurutan di seluruh
JsonDocumentmelalui setiap properti dengan menggunakanRootElement. Sebagai gantinya, cari objek JSON berlapis berdasarkan struktur data JSON yang diketahui. Misalnya, contoh kode sebelumnya mencari propertiGradedi objekStudentdengan mengulang objekStudentdan mendapatkan nilaiGradeuntuk masing-masing, daripada menelusuri semuaJsonElementobjek mencari propertiGrade. Melakukan yang terakhir akan mengakibatkan melewati data yang sama yang tidak perlu.
Membandingkan JsonElements
Untuk membandingkan dua JsonElement objek untuk kesetaraan, termasuk elemen turunannya, gunakan metode .JsonElement.DeepEquals(JsonElement, JsonElement)
JsonElement left = JsonDocument.Parse("10e-3").RootElement;
JsonElement right = JsonDocument.Parse("0.01").RootElement;
bool equal = JsonElement.DeepEquals(left, right);
Console.WriteLine(equal); // True.
Gunakan JsonDocument untuk menulis JSON
Contoh berikut menunjukkan cara menulis JSON dari JsonDocument:
string jsonString = File.ReadAllText(inputFileName);
var writerOptions = new JsonWriterOptions
{
Indented = true
};
var documentOptions = new JsonDocumentOptions
{
CommentHandling = JsonCommentHandling.Skip
};
using FileStream fs = File.Create(outputFileName);
using var writer = new Utf8JsonWriter(fs, options: writerOptions);
using JsonDocument document = JsonDocument.Parse(jsonString, documentOptions);
JsonElement root = document.RootElement;
if (root.ValueKind == JsonValueKind.Object)
{
writer.WriteStartObject();
}
else
{
return;
}
foreach (JsonProperty property in root.EnumerateObject())
{
property.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
Dim jsonString As String = File.ReadAllText(inputFileName)
Dim writerOptions As JsonWriterOptions = New JsonWriterOptions With {
.Indented = True
}
Dim documentOptions As JsonDocumentOptions = New JsonDocumentOptions With {
.CommentHandling = JsonCommentHandling.Skip
}
Dim fs As FileStream = File.Create(outputFileName)
Dim writer As Utf8JsonWriter = New Utf8JsonWriter(fs, options:=writerOptions)
Dim document As JsonDocument = JsonDocument.Parse(jsonString, documentOptions)
Dim root As JsonElement = document.RootElement
If root.ValueKind = JsonValueKind.[Object] Then
writer.WriteStartObject()
Else
Return
End If
For Each [property] As JsonProperty In root.EnumerateObject()
[property].WriteTo(writer)
Next
writer.WriteEndObject()
writer.Flush()
Kode sebelumnya:
- Membaca file JSON, memuat data ke dalam
JsonDocument, dan menulis JSON yang diformat (cukup dicetak) ke file. - Menggunakan JsonDocumentOptions untuk menentukan bahwa komentar dalam input JSON diizinkan tetapi diabaikan.
- Setelah selesai, panggilan Flush pada penulis. Alternatifnya adalah membiarkan penulis melakukan flush otomatis saat dibuang.
Berikut adalah contoh input JSON yang akan diproses oleh kode contoh:
{"Class Name": "Science","Teacher's Name": "Jane","Semester": "2019-01-01","Students": [{"Name": "John","Grade": 94.3},{"Name": "James","Grade": 81.0},{"Name": "Julia","Grade": 91.9},{"Name": "Jessica","Grade": 72.4},{"Name": "Johnathan"}],"Final": true}
Hasilnya adalah output JSON yang cukup dicetak berikut:
{
"Class Name": "Science",
"Teacher\u0027s Name": "Jane",
"Semester": "2019-01-01",
"Students": [
{
"Name": "John",
"Grade": 94.3
},
{
"Name": "James",
"Grade": 81.0
},
{
"Name": "Julia",
"Grade": 91.9
},
{
"Name": "Jessica",
"Grade": 72.4
},
{
"Name": "Johnathan"
}
],
"Final": true
}
JsonDocument adalah IDisposable
JsonDocument membuat tampilan data dalam memori ke dalam buffer yang dikumpulkan. Oleh karena itu, jenis JsonDocument mengimplementasikan IDisposable dan perlu digunakan di dalam blok using.
Hanya kembalikan JsonDocument dari API Anda jika Anda ingin mentransfer kepemilikan seumur hidup dan membuang tanggung jawab kepada pemanggil. Dalam kebanyakan skenario, hal ini tidak perlu. Jika pemanggil perlu bekerja dengan seluruh dokumen JSON, kembalikan Clone dari RootElement, yang merupakan JsonElement. Jika pemanggil perlu bekerja dengan elemen tertentu dalam dokumen JSON, kembalikan Clone dari JsonElement tersebut. Jika Anda mengembalikan RootElement atau subelemen secara langsung tanpa membuat Clone, pemanggil tidak akan dapat mengakses JsonElement yang dikembalikan setelah JsonDocument yang memilikinya dibuang.
Berikut adalah contoh yang mengharuskan Anda membuat Clone:
public JsonElement LookAndLoad(JsonElement source)
{
string json = File.ReadAllText(source.GetProperty("fileName").GetString());
using (JsonDocument doc = JsonDocument.Parse(json))
{
return doc.RootElement.Clone();
}
}
Kode sebelumnya mengharapkan JsonElement yang berisi properti fileName. Hal ini akan membuka file JSON dan membuat JsonDocument. Metode ini mengasumsikan bahwa pemanggil ingin bekerja dengan seluruh dokumen, sehingga mengembalikan Clone dari RootElement.
Jika Anda menerima JsonElement dan mengembalikan subelemen, tidak perlu mengembalikan subelemen Clone. Penelepon bertanggung jawab untuk menjaga agar JsonDocument yang diteruskan JsonElement tetap aktif. Contohnya:
public JsonElement ReturnFileName(JsonElement source)
{
return source.GetProperty("fileName");
}
JsonDocumentdenganJsonSerializerOptions
Anda dapat menggunakan JsonSerializer untuk menserialisasikan dan mendeserialisasi instans JsonDocument. Namun, implementasi untuk membaca dan menulis instans JsonDocument dengan menggunakan JsonSerializer merupakan pembungkus dari JsonDocument.ParseValue(Utf8JsonReader) dan JsonDocument.WriteTo(Utf8JsonWriter). Pembungkus ini tidak meneruskan JsonSerializerOptions (fitur serializer) apa pun ke Utf8JsonReader atau Utf8JsonWriter. Misalnya, jika Anda menyetel JsonSerializerOptions.DefaultIgnoreCondition ke WhenWritingNull dan memanggil JsonSerializer dengan overload yang membutuhkan JsonSerializerOptions, properti null tidak akan diabaikan.
Contoh berikut mengilustrasikan hasil penggunaan metode yang mengambil parameter JsonSerializerOptions dan membuat serial instans JsonDocument:
using System.Text.Json;
using System.Text.Json.Serialization;
namespace JsonDocumentWithJsonSerializerOptions;
public class Program
{
public static void Main()
{
Person person = new() { Name = "Nancy" };
// Default serialization - Address property included with null token.
// Output: {"Name":"Nancy","Address":null}
string personJsonWithNull = JsonSerializer.Serialize(person);
Console.WriteLine(personJsonWithNull);
// Serialize and ignore null properties - null Address property is omitted
// Output: {"Name":"Nancy"}
JsonSerializerOptions options = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
string personJsonWithoutNull = JsonSerializer.Serialize(person, options);
Console.WriteLine(personJsonWithoutNull);
// Ignore null properties doesn't work when serializing JsonDocument instance
// by using JsonSerializer.
// Output: {"Name":"Nancy","Address":null}
JsonDocument? personJsonDocument = JsonSerializer.Deserialize<JsonDocument>(personJsonWithNull);
personJsonWithNull = JsonSerializer.Serialize(personJsonDocument, options);
Console.WriteLine(personJsonWithNull);
}
}
public class Person
{
public string? Name { get; set; }
public string? Address { get; set; }
}
Jika Anda memerlukan fitur JsonSerializerOptions, gunakan JsonSerializer dengan target yang diketik dengan kuat (seperti kelas Person dalam contoh ini) daripada JsonDocument.