Megosztás a következőn keresztül:


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 JsonNodea 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"
//  ]
//}

Lásd még