A túlcsordulásos JSON kezelése vagy a JsonElement vagy a JsonNode használata
Ez a cikk bemutatja, hogyan kezelhető a túlcsordulásos JSON a System.Text.Json névtérrel. Azt is bemutatja, hogyan lehet deszerializálni a deszerializálást JsonElement JsonNodemás forgatókönyvek esetében, ahol a céltípus nem feltétlenül felel meg az összes deszerializált JSON-nak.
Túlcsordulás kezelése JSON
A deszerializálás során olyan JSON-adatokat kaphat, amelyeket nem a céltípus tulajdonságai jelölnek. Tegyük fel például, hogy a céltípus a következő:
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
A deszerializálandó JSON pedig a következő:
{
"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"
]
}
Ha deszerializálja a megjelenített JSON-t a megjelenített típusba, a DatesAvailable
tulajdonságoknak SummaryWords
nincs hová menniük, és elvesznek. Az ilyen tulajdonságokhoz hasonló további adatok rögzítéséhez alkalmazza a [JsonExtensionData] attribútumot egy típus Dictionary<string,object>
vagy 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
Az alábbi táblázat a korábban bemutatott JSON deszerializálásának eredményét mutatja be ebben a mintatípusban. A további adatok a tulajdonság kulcs-érték párjaivá ExtensionData
válnak:
Tulajdonság | Érték | Jegyzetek |
---|---|---|
Date |
"8/1/2019 12:00:00 AM -07:00" |
|
TemperatureCelsius |
0 |
A kis- és nagybetűk megkülönböztetése (temperatureCelsius a JSON-ban), így a tulajdonság nincs beállítva. |
Summary |
"Hot" |
|
ExtensionData |
"temperatureCelsius": 25, "DatesAvailable": ["2019-08-01T00:00:00-07:00","2019-08-02T00:00:00-07:00"], "SummaryWords": ["Cool","Windy","Humid"] |
Mivel az eset nem egyezik, ez egy extra, temperatureCelsius és kulcs-érték pár lesz a szótárban. A JSON-ból származó további tömbök kulcs-érték párok lesznek, és egy tömb lesz az értékobjektum. |
A célobjektum szerializálása után a bővítmény adatkulcs-értékpárjai ugyanúgy JSON-tulajdonságokká válnak, mint a bejövő JSON-ban:
{
"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"
]
}
Figyelje meg, hogy a ExtensionData
tulajdonság neve nem jelenik meg a JSON-ban. Ez a viselkedés lehetővé teszi a JSON számára, hogy egy oda-vissza utazást tegyen anélkül, hogy elveszítene minden olyan adatot, amely egyébként nem lenne deszerializálva.
Az alábbi példa egy JSON-ról egy deszerializált objektumra való oda-vissza utazást mutat be, és vissza a JSON-ba:
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"
// ]
//}
Deszerializálás JsonElement vagy JsonNode formátumba
Ha csak azt szeretné, hogy rugalmas legyen azzal kapcsolatban, hogy a JSON milyen elfogadható egy adott tulajdonsághoz, alternatív megoldásként deszerializálhatja JsonElement azt vagy JsonNode. Bármely érvényes JSON-tulajdonság deszerializálható a(z) vagy JsonNode
a JsonElement
. Válassza JsonElement
ki, hogy létrehoz-e nem módosítható objektumot, vagy JsonNode
hozzon létre egy mutable objektumot.
Az alábbi példa egy JSON-ról visszafelé tartó utat mutat be egy olyan osztályhoz, amely típus JsonElement
- és 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"
// ]
//}