Hantera spill-JSON eller använda JsonElement eller JsonNode
Den här artikeln visar hur du hanterar spill-JSON med System.Text.Json namnområdet. Den visar också hur du deserialiserar till JsonElement eller JsonNode, som ett alternativ för andra scenarier där måltypen kanske inte helt matchar alla JSON som deserialiseras.
Hantera spill-JSON
Vid deserialisering kan du få data i JSON som inte representeras av egenskaper av måltypen. Anta till exempel att din måltyp är följande:
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
Och JSON som ska deserialiseras är följande:
{
"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"
]
}
Om du deserialiserar JSON som visas i den typ som visas har DatesAvailable
egenskaperna och SummaryWords
ingenstans att ta vägen och går förlorade. Om du vill samla in extra data, till exempel dessa egenskaper, använder du attributet [JsonExtensionData] på en egenskap av typen Dictionary<string,object>
eller 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
I följande tabell visas resultatet av deserialisering av JSON som visades tidigare i den här exempeltypen. De extra data blir nyckel/värde-par för ExtensionData
egenskapen:
Property | Värde | Kommentar |
---|---|---|
Date |
"8/1/2019 12:00:00 AM -07:00" |
|
TemperatureCelsius |
0 |
Skiftlägeskänslig matchning (temperatureCelsius i JSON), så egenskapen har inte angetts. |
Summary |
"Hot" |
|
ExtensionData |
"temperatureCelsius": 25, "DatesAvailable": ["2019-08-01T00:00:00-07:00","2019-08-02T00:00:00-07:00"], "SummaryWords": ["Cool","Windy","Humid"] |
Eftersom fallet inte matchade temperatureCelsius är det ett extra och blir ett nyckel/värde-par i ordlistan. Varje extra matris från JSON blir ett nyckel/värde-par, med en matris som värdeobjekt. |
När målobjektet serialiseras blir tilläggsdatanyckelparen JSON-egenskaper precis som i den inkommande JSON:en:
{
"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"
]
}
Observera att egenskapsnamnet ExtensionData
inte visas i JSON. Med det här beteendet kan JSON göra en tur och retur utan att förlora några extra data som annars inte skulle deserialiseras.
I följande exempel visas en tur och retur-resa från JSON till ett deserialiserat objekt och tillbaka till 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"
// ]
//}
Deserialisera till JsonElement eller JsonNode
Om du bara vill vara flexibel om vad JSON är acceptabelt för en viss egenskap är ett alternativ att deserialisera till JsonElement eller JsonNode. Alla giltiga JSON-egenskaper kan deserialiseras till JsonElement
eller JsonNode
. Välj JsonElement
att skapa ett oföränderligt objekt eller JsonNode
skapa ett föränderligt objekt.
I följande exempel visas en tur- och returresa från JSON och tillbaka till JSON för en klass som innehåller egenskaper av typen JsonElement
och 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"
// ]
//}