Bagikan melalui


Cara menangani luapan JSON atau menggunakan JsonElement atau JsonNode di System.Text.Json

Artikel ini menunjukkan cara menangani luapan JSON dengan kumpulan nama XML System.Text.Json. Ini juga menunjukkan cara mendeserialisasi menjadi JsonElement atau JsonNode, sebagai alternatif untuk skenario lain di mana jenis target mungkin tidak cocok dengan semua JSON yang sedang dideserialisasi.

Menangani luapan JSON

Saat deserialisasi, Anda mungkin menerima data di JSON yang tidak diwakili oleh properti dari jenis target. Misalnya, anggap saja jenis target Anda adalah ini:

public class WeatherForecast
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
}
Public Class WeatherForecast
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String
End Class

Dan JSON yang akan dideserialisasi adalah ini:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "temperatureCelsius": 25,
  "Summary": "Hot",
  "DatesAvailable": [
    "2019-08-01T00:00:00-07:00",
    "2019-08-02T00:00:00-07:00"
  ],
  "SummaryWords": [
    "Cool",
    "Windy",
    "Humid"
  ]
}

Jika Anda mendeserialisasi JSON yang ditampilkan ke dalam jenis yang ditampilkan, properti DatesAvailable dan SummaryWords tidak memiliki tempat untuk dituju dan akan hilang. Untuk mengambil data tambahan seperti properti ini, terapkan atribut [JsonExtensionData] ke properti dengan jenis Dictionary<string,object> atau Dictionary<string,JsonElement>:

public class WeatherForecastWithExtensionData
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
    [JsonExtensionData]
    public Dictionary<string, JsonElement>? ExtensionData { get; set; }
}
Public Class WeatherForecastWithExtensionData
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String

    <JsonExtensionData>
    Public Property ExtensionData As Dictionary(Of String, Object)

End Class

Tabel berikut menunjukkan hasil deserialisasi JSON yang ditunjukkan sebelumnya ke dalam jenis sampel ini. Data tambahan menjadi pasangan kunci-nilai dari properti ExtensionData:

Properti Nilai Catatan
Date "8/1/2019 12:00:00 AM -07:00"
TemperatureCelsius 0 Ketidakcocokan peka huruf besar/kecil (temperatureCelsius di JSON), jadi properti tidak diatur.
Summary "Hot"
ExtensionData "temperatureCelsius": 25,
"DatesAvailable": ["2019-08-01T00:00:00-07:00","2019-08-02T00:00:00-07:00"],
"SummaryWords": ["Cool","Windy","Humid"]
Karena hurufnya tidak cocok, temperatureCelsius adalah tambahan dan menjadi pasangan kunci-nilai dalam kamus.
Setiap array tambahan dari JSON menjadi pasangan kunci-nilai, dengan array sebagai objek nilai.

Saat objek target diserialisasi, pasangan kunci-nilai data ekstensi menjadi properti JSON, sama seperti di JSON yang masuk:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 0,
  "Summary": "Hot",
  "temperatureCelsius": 25,
  "DatesAvailable": [
    "2019-08-01T00:00:00-07:00",
    "2019-08-02T00:00:00-07:00"
  ],
  "SummaryWords": [
    "Cool",
    "Windy",
    "Humid"
  ]
}

Perhatikan bahwa nama properti ExtensionData tidak muncul di JSON. Perilaku ini memungkinkan JSON melakukan perjalanan pulang-pergi tanpa kehilangan data tambahan yang, jika tidak, tidak akan dideserialisasi.

Contoh berikut menunjukkan perjalanan pulang-pergi dari JSON ke objek deserialisasi dan kembali ke JSON:

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

namespace RoundtripExtensionData
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
        [JsonExtensionData]
        public Dictionary<string, JsonElement>? ExtensionData { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            string jsonString =
@"{
  ""Date"": ""2019-08-01T00:00:00-07:00"",
  ""temperatureCelsius"": 25,
  ""Summary"": ""Hot"",
  ""SummaryField"": ""Hot"",
  ""DatesAvailable"": [
    ""2019-08-01T00:00:00-07:00"",
    ""2019-08-02T00:00:00-07:00""
  ],
  ""SummaryWords"": [
    ""Cool"",
    ""Windy"",
    ""Humid""
  ]
}";
            WeatherForecast weatherForecast = 
                JsonSerializer.Deserialize<WeatherForecast>(jsonString)!;

            var serializeOptions = new JsonSerializerOptions { WriteIndented = true };
            jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions);
            Console.WriteLine($"JSON output:\n{jsonString}\n");
        }
    }
}
// output:
//JSON output:
//{
//  "Date": "2019-08-01T00:00:00-07:00",
//  "TemperatureCelsius": 0,
//  "Summary": "Hot",
//  "temperatureCelsius": 25,
//  "SummaryField": "Hot",
//  "DatesAvailable": [
//    "2019-08-01T00:00:00-07:00",
//    "2019-08-02T00:00:00-07:00"
//  ],
//  "SummaryWords": [
//    "Cool",
//    "Windy",
//    "Humid"
//  ]
//}

Mendeserialisasi ke JsonElement atau JsonNode

Jika Anda hanya ingin fleksibel tentang apa yang dapat diterima JSON untuk properti tertentu, alternatifnya adalah mendeserialisasi ke dalam JsonElement atau JsonNode. Setiap properti JSON yang valid dapat dideserialisasi menjadi JsonElement atau JsonNode. Pilih JsonElement untuk membuat objek yang tidak dapat diubah atau JsonNode untuk membuat objek yang dapat diubah.

Contoh berikut menunjukkan perjalanan pulang-pergi dari JSON dan kembali ke JSON untuk kelas yang menyertakan properti berjenis JsonElement dan JsonNode.

using System.Text.Json;
using System.Text.Json.Nodes;

namespace RoundtripJsonElementAndNode
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
        public JsonElement DatesAvailable { get; set; }
        public JsonNode? SummaryWords { get; set; }
    }
        public class Program
    {
        public static void Main()
        {
            string jsonString =
@"{
  ""Date"": ""2019-08-01T00:00:00-07:00"",
  ""TemperatureCelsius"": 25,
  ""Summary"": ""Hot"",
  ""DatesAvailable"": [
    ""2019-08-01T00:00:00-07:00"",
    ""2019-08-02T00:00:00-07:00""
  ],
  ""SummaryWords"": [
    ""Cool"",
    ""Windy"",
    ""Humid""
  ]
}";
            WeatherForecast? weatherForecast = 
                JsonSerializer.Deserialize<WeatherForecast>(jsonString);

            var serializeOptions = new JsonSerializerOptions { WriteIndented = true };
            jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions);
            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{
//  "Date": "2019-08-01T00:00:00-07:00",
//  "TemperatureCelsius": 25,
//  "Summary": "Hot",
//  "DatesAvailable": [
//    "2019-08-01T00:00:00-07:00",
//    "2019-08-02T00:00:00-07:00"
//  ],
//  "SummaryWords": [
//    "Cool",
//    "Windy",
//    "Humid"
//  ]
//}

Lihat juga