Cara menangani JSON luapan atau menggunakan JsonElement atau JsonNode
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"
// ]
//}