Bagikan melalui


Cara menggunakan model objek dokumen JSON di System.Text.Json

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. Jenis JsonElement ini menyediakan enumerator array dan objek bersama dengan API untuk mengonversi teks JSON ke jenis .NET umum. JsonDocument mengekspos 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 JsonNode nanti di artikel ini.

Pertimbangkan faktor-faktor berikut saat memilih antara JsonDocument dan JsonNode:

  • DOM JsonNode dapat diubah setelah dibuat. DOM JsonDocument tidak dapat diubah.
  • DOM JsonDocument menyediakan 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)!;

        JsonNode root = document.Root;
        JsonArray studentsArray = root["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 Students array yang memiliki properti Grade.
  • Menetapkan nilai default 70 untuk siswa yang tidak memiliki nilai.
  • Mendapatkan jumlah siswa dari properti Count pada JsonArray.

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.

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 Students array yang memiliki properti Grade.
  • Menetapkan nilai default 70 untuk siswa yang tidak memiliki nilai.
  • Membuat instans JsonDocument dalam using pernyataan karena JsonDocument mengimplementasikan IDisposable. Setelah instans JsonDocument dibuang, Anda juga kehilangan akses ke semua instans JsonElement. Untuk mempertahankan akses ke instans JsonElement, buat salinannya sebelum instans JsonDocument induk 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 JsonDocument melalui setiap properti dengan menggunakan RootElement. Sebagai gantinya, cari objek JSON berlapis berdasarkan struktur data JSON yang diketahui. Misalnya, contoh kode sebelumnya mencari properti Grade di objek Student dengan mengulang objek Student dan mendapatkan nilai Grade untuk masing-masing, daripada menelusuri semua JsonElement objek mencari properti Grade. Melakukan yang terakhir akan mengakibatkan melewati data yang sama yang tidak perlu.

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.

Lihat juga