Så här använder du en JSON-dokumentobjektmodell i System.Text.Json
Den här artikeln visar hur du använder en JSON-dokumentobjektmodell (DOM) för slumpmässig åtkomst till data i en JSON-nyttolast.
JSON DOM-val
Att arbeta med en DOM är ett alternativ till deserialisering med JsonSerializer när:
- Du har ingen typ att deserialisera till.
- JSON-filen som du får har inget fast schema och måste inspekteras för att veta vad den innehåller.
System.Text.Json
innehåller två sätt att skapa en JSON DOM:
JsonDocument ger möjlighet att skapa en skrivskyddad DOM med hjälp
Utf8JsonReader
av . JSON-elementen som utgör nyttolasten kan nås via JsonElement typen . TypenJsonElement
innehåller matris- och objektuppräknare tillsammans med API:er för att konvertera JSON-text till vanliga .NET-typer.JsonDocument
exponerar en RootElement egenskap. Mer information finns i Använda JsonDocument senare i den här artikeln.JsonNode och klasserna som härleds från den i System.Text.Json.Nodes namnområdet ger möjlighet att skapa en föränderlig DOM. JSON-elementen som utgör nyttolasten kan nås via typerna JsonNode, JsonObject, JsonArray, JsonValueoch JsonElement . Mer information finns i Använda
JsonNode
senare i den här artikeln.
Tänk på följande faktorer när du väljer mellan JsonDocument
och JsonNode
:
- DOM
JsonNode
kan ändras när den har skapats. DOMJsonDocument
är oföränderlig. JsonDocument
DOM ger snabbare åtkomst till sina data.
Använda JsonNode
I följande exempel visas hur du använder JsonNode och de andra typerna System.Text.Json.Nodes i namnområdet till:
- Skapa en DOM från en JSON-sträng
- Skriv JSON från en DOM.
- Hämta ett värde, ett objekt eller en matris från en DOM.
using System.Text.Json;
using System.Text.Json.Nodes;
namespace JsonNodeFromStringExample;
public class Program
{
public static void Main()
{
string jsonString = """
{
"Date": "2019-08-01T00:00:00",
"Temperature": 25,
"Summary": "Hot",
"DatesAvailable": [
"2019-08-01T00:00:00",
"2019-08-02T00:00:00"
],
"TemperatureRanges": {
"Cold": {
"High": 20,
"Low": -10
},
"Hot": {
"High": 60,
"Low": 20
}
}
}
""";
// Create a JsonNode DOM from a JSON string.
JsonNode forecastNode = JsonNode.Parse(jsonString)!;
// Write JSON from a JsonNode
var options = new JsonSerializerOptions { WriteIndented = true };
Console.WriteLine(forecastNode!.ToJsonString(options));
// output:
//{
// "Date": "2019-08-01T00:00:00",
// "Temperature": 25,
// "Summary": "Hot",
// "DatesAvailable": [
// "2019-08-01T00:00:00",
// "2019-08-02T00:00:00"
// ],
// "TemperatureRanges": {
// "Cold": {
// "High": 20,
// "Low": -10
// },
// "Hot": {
// "High": 60,
// "Low": 20
// }
// }
//}
// Get value from a JsonNode.
JsonNode temperatureNode = forecastNode!["Temperature"]!;
Console.WriteLine($"Type={temperatureNode.GetType()}");
Console.WriteLine($"JSON={temperatureNode.ToJsonString()}");
//output:
//Type = System.Text.Json.Nodes.JsonValue`1[System.Text.Json.JsonElement]
//JSON = 25
// Get a typed value from a JsonNode.
int temperatureInt = (int)forecastNode!["Temperature"]!;
Console.WriteLine($"Value={temperatureInt}");
//output:
//Value=25
// Get a typed value from a JsonNode by using GetValue<T>.
temperatureInt = forecastNode!["Temperature"]!.GetValue<int>();
Console.WriteLine($"TemperatureInt={temperatureInt}");
//output:
//Value=25
// Get a JSON object from a JsonNode.
JsonNode temperatureRanges = forecastNode!["TemperatureRanges"]!;
Console.WriteLine($"Type={temperatureRanges.GetType()}");
Console.WriteLine($"JSON={temperatureRanges.ToJsonString()}");
//output:
//Type = System.Text.Json.Nodes.JsonObject
//JSON = { "Cold":{ "High":20,"Low":-10},"Hot":{ "High":60,"Low":20} }
// Get a JSON array from a JsonNode.
JsonNode datesAvailable = forecastNode!["DatesAvailable"]!;
Console.WriteLine($"Type={datesAvailable.GetType()}");
Console.WriteLine($"JSON={datesAvailable.ToJsonString()}");
//output:
//datesAvailable Type = System.Text.Json.Nodes.JsonArray
//datesAvailable JSON =["2019-08-01T00:00:00", "2019-08-02T00:00:00"]
// Get an array element value from a JsonArray.
JsonNode firstDateAvailable = datesAvailable[0]!;
Console.WriteLine($"Type={firstDateAvailable.GetType()}");
Console.WriteLine($"JSON={firstDateAvailable.ToJsonString()}");
//output:
//Type = System.Text.Json.Nodes.JsonValue`1[System.Text.Json.JsonElement]
//JSON = "2019-08-01T00:00:00"
// Get a typed value by chaining references.
int coldHighTemperature = (int)forecastNode["TemperatureRanges"]!["Cold"]!["High"]!;
Console.WriteLine($"TemperatureRanges.Cold.High={coldHighTemperature}");
//output:
//TemperatureRanges.Cold.High = 20
// Parse a JSON array
var datesNode = JsonNode.Parse(@"[""2019-08-01T00:00:00"",""2019-08-02T00:00:00""]");
JsonNode firstDate = datesNode![0]!.GetValue<DateTime>();
Console.WriteLine($"firstDate={ firstDate}");
//output:
//firstDate = "2019-08-01T00:00:00"
}
}
Skapa en JsonNode DOM med objektinitierare och gör ändringar
I följande exempel visas hur du:
- Skapa en DOM med hjälp av objektinitierare.
- Gör ändringar i en DOM.
using System.Text.Json;
using System.Text.Json.Nodes;
namespace JsonNodeFromObjectExample;
public class Program
{
public static void Main()
{
// Create a new JsonObject using object initializers.
var forecastObject = new JsonObject
{
["Date"] = new DateTime(2019, 8, 1),
["Temperature"] = 25,
["Summary"] = "Hot",
["DatesAvailable"] = new JsonArray(
new DateTime(2019, 8, 1), new DateTime(2019, 8, 2)),
["TemperatureRanges"] = new JsonObject
{
["Cold"] = new JsonObject
{
["High"] = 20,
["Low"] = -10
}
},
["SummaryWords"] = new JsonArray("Cool", "Windy", "Humid")
};
// Add an object.
forecastObject!["TemperatureRanges"]!["Hot"] =
new JsonObject { ["High"] = 60, ["Low"] = 20 };
// Remove a property.
forecastObject.Remove("SummaryWords");
// Change the value of a property.
forecastObject["Date"] = new DateTime(2019, 8, 3);
var options = new JsonSerializerOptions { WriteIndented = true };
Console.WriteLine(forecastObject.ToJsonString(options));
//output:
//{
// "Date": "2019-08-03T00:00:00",
// "Temperature": 25,
// "Summary": "Hot",
// "DatesAvailable": [
// "2019-08-01T00:00:00",
// "2019-08-02T00:00:00"
// ],
// "TemperatureRanges": {
// "Cold": {
// "High": 20,
// "Low": -10
// },
// "Hot": {
// "High": 60,
// "Low": 20
// }
// }
//}
}
}
Deserialisera underavsnitt för en JSON-nyttolast
I följande exempel visas hur du använder JsonNode för att navigera till ett underavsnitt av ett JSON-träd och deserialisera ett enda värde, en anpassad typ eller en matris från den underavsnittet.
using System.Text.Json;
using System.Text.Json.Nodes;
namespace JsonNodePOCOExample;
public class TemperatureRanges : Dictionary<string, HighLowTemps>
{
}
public class HighLowTemps
{
public int High { get; set; }
public int Low { get; set; }
}
public class Program
{
public static DateTime[]? DatesAvailable { get; set; }
public static void Main()
{
string jsonString = """
{
"Date": "2019-08-01T00:00:00",
"Temperature": 25,
"Summary": "Hot",
"DatesAvailable": [
"2019-08-01T00:00:00",
"2019-08-02T00:00:00"
],
"TemperatureRanges": {
"Cold": {
"High": 20,
"Low": -10
},
"Hot": {
"High": 60,
"Low": 20
}
}
}
""";
// Parse all of the JSON.
JsonNode forecastNode = JsonNode.Parse(jsonString)!;
// Get a single value
int hotHigh = forecastNode["TemperatureRanges"]!["Hot"]!["High"]!.GetValue<int>();
Console.WriteLine($"Hot.High={hotHigh}");
// output:
//Hot.High=60
// Get a subsection and deserialize it into a custom type.
JsonObject temperatureRangesObject = forecastNode!["TemperatureRanges"]!.AsObject();
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream);
temperatureRangesObject.WriteTo(writer);
writer.Flush();
TemperatureRanges? temperatureRanges =
JsonSerializer.Deserialize<TemperatureRanges>(stream.ToArray());
Console.WriteLine($"Cold.Low={temperatureRanges!["Cold"].Low}, Hot.High={temperatureRanges["Hot"].High}");
// output:
//Cold.Low=-10, Hot.High=60
// Get a subsection and deserialize it into an array.
JsonArray datesAvailable = forecastNode!["DatesAvailable"]!.AsArray()!;
Console.WriteLine($"DatesAvailable[0]={datesAvailable[0]}");
// output:
//DatesAvailable[0]=8/1/2019 12:00:00 AM
}
}
Exempel på JsonNode-genomsnittsbetyg
I följande exempel väljs en JSON-matris som har heltalsvärden och beräknar ett genomsnittligt värde:
using System.Text.Json.Nodes;
namespace JsonNodeAverageGradeExample;
public class Program
{
public static void Main()
{
string jsonString = """
{
"Class Name": "Science",
"Teacher\u0027s Name": "Jane",
"Semester": "2019-01-01",
"Students": [
{
"Name": "John",
"Grade": 94.3
},
{
"Name": "James",
"Grade": 81.0
},
{
"Name": "Julia",
"Grade": 91.9
},
{
"Name": "Jessica",
"Grade": 72.4
},
{
"Name": "Johnathan"
}
],
"Final": true
}
""";
double sum = 0;
JsonNode document = JsonNode.Parse(jsonString)!;
JsonNode root = document.Root;
JsonArray studentsArray = root["Students"]!.AsArray();
int count = studentsArray.Count;
foreach (JsonNode? student in studentsArray)
{
if (student?["Grade"] is JsonNode gradeNode)
{
sum += (double)gradeNode;
}
else
{
sum += 70;
}
}
double average = sum / count;
Console.WriteLine($"Average grade : {average}");
}
}
// output:
//Average grade : 81.92
Koden ovan:
- Beräknar ett genomsnittsbetyg för objekt i en
Students
matris som har enGrade
egenskap. - Tilldelar ett standardbetyg på 70 för elever som inte har ett betyg.
- Hämtar antalet studenter från
Count
egenskapenJsonArray
.
JsonNode
med JsonSerializerOptions
Du kan använda JsonSerializer
för att serialisera och deserialisera en instans av JsonNode
. Men om du använder en överlagring som tar JsonSerializerOptions
används alternativinstansen endast för att hämta anpassade konverterare. Andra funktioner i alternativinstansen används inte. Om du till exempel ställer in JsonSerializerOptions.DefaultIgnoreCondition på WhenWritingNull och anropar JsonSerializer
med en överlagring som tar JsonSerializerOptions
ignoreras inte null-egenskaper.
Samma begränsning gäller för de JsonNode
metoder som använder en JsonSerializerOptions
parameter: WriteTo(Utf8JsonWriter, JsonSerializerOptions) och ToJsonString(JsonSerializerOptions). Dessa API:er används JsonSerializerOptions
endast för att hämta anpassade konverterare.
I följande exempel visas resultatet av att använda metoder som tar en JsonSerializerOptions
parameter och serialiserar en JsonNode
instans:
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace JsonNodeWithJsonSerializerOptions;
public class Program
{
public static void Main()
{
Person person = new() { Name = "Nancy" };
// Default serialization - Address property included with null token.
// Output: {"Name":"Nancy","Address":null}
string personJsonWithNull = JsonSerializer.Serialize(person);
Console.WriteLine(personJsonWithNull);
// Serialize and ignore null properties - null Address property is omitted
// Output: {"Name":"Nancy"}
JsonSerializerOptions options = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
string personJsonWithoutNull = JsonSerializer.Serialize(person, options);
Console.WriteLine(personJsonWithoutNull);
// Ignore null properties doesn't work when serializing JsonNode instance
// by using JsonSerializer.
// Output: {"Name":"Nancy","Address":null}
JsonNode? personJsonNode = JsonSerializer.Deserialize<JsonNode>(personJsonWithNull);
personJsonWithNull = JsonSerializer.Serialize(personJsonNode, options);
Console.WriteLine(personJsonWithNull);
// Ignore null properties doesn't work when serializing JsonNode instance
// by using JsonNode.ToJsonString method.
// Output: {"Name":"Nancy","Address":null}
personJsonWithNull = personJsonNode!.ToJsonString(options);
Console.WriteLine(personJsonWithNull);
// Ignore null properties doesn't work when serializing JsonNode instance
// by using JsonNode.WriteTo method.
// Output: {"Name":"Nancy","Address":null}
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream);
personJsonNode!.WriteTo(writer, options);
writer.Flush();
personJsonWithNull = Encoding.UTF8.GetString(stream.ToArray());
Console.WriteLine(personJsonWithNull);
}
}
public class Person
{
public string? Name { get; set; }
public string? Address { get; set; }
}
Om du behöver andra funktioner JsonSerializerOptions
än anpassade konverterare använder JsonSerializer
du med starkt skrivna mål (till exempel Person
klassen i det här exemplet) i stället JsonNode
för .
Ändra egenskapsordning
JsonObject är ett av elementen i nyttolasten för ett JsonNode, och det representerar ett föränderligt JSON-objekt. Även om typen modelleras som en IDictionary<string, JsonNode>
, där varje post är en egenskap för objektet, kapslar den in en implicit egenskapsordning. API:er som Insert(Int32, String, JsonNode) och RemoveAt(Int32) modellerar effektivt typen som en ordnad ordlista genom att låta dig infoga och ta bort objekt i ett specifikt index. Dessa API:er tillåter ändringar i objektinstanser som direkt kan påverka egenskapsordningen.
Följande kod visar ett exempel på hur du lägger till eller flyttar en specifik egenskap till början av objektet.
var schema = (JsonObject)JsonSerializerOptions.Default.GetJsonSchemaAsNode(typeof(MyPoco));
JsonNode? idValue;
switch (schema.IndexOf("$id"))
{
// $id property missing.
case < 0:
idValue = (JsonNode)"https://example.com/schema";
schema.Insert(0, "$id", idValue);
break;
// $id property already at the start of the object.
case 0:
break;
// $id exists but not at the start of the object.
case int index:
idValue = schema[index];
schema.RemoveAt(index);
schema.Insert(0, "$id", idValue);
break;
}
Jämför JsonNodes
Om du vill jämföra två JsonNode
objekt för likhet, inklusive deras underordnade element, använder du JsonNode.DeepEquals(JsonNode, JsonNode) metoden.
Använda JsonDocument
I följande exempel visas hur du använder JsonDocument klassen för slumpmässig åtkomst till data i en JSON-sträng:
double sum = 0;
int count = 0;
using (JsonDocument document = JsonDocument.Parse(jsonString))
{
JsonElement root = document.RootElement;
JsonElement studentsElement = root.GetProperty("Students");
foreach (JsonElement student in studentsElement.EnumerateArray())
{
if (student.TryGetProperty("Grade", out JsonElement gradeElement))
{
sum += gradeElement.GetDouble();
}
else
{
sum += 70;
}
count++;
}
}
double average = sum / count;
Console.WriteLine($"Average grade : {average}");
Dim sum As Double = 0
Dim count As Integer = 0
Using document As JsonDocument = JsonDocument.Parse(jsonString)
Dim root As JsonElement = document.RootElement
Dim studentsElement As JsonElement = root.GetProperty("Students")
For Each student As JsonElement In studentsElement.EnumerateArray()
Dim gradeElement As JsonElement = Nothing
If student.TryGetProperty("Grade", gradeElement) Then
sum += gradeElement.GetDouble()
Else
sum += 70
End If
count += 1
Next
End Using
Dim average As Double = sum / count
Console.WriteLine($"Average grade : {average}")
Koden ovan:
- Förutsätter att JSON som ska analyseras finns i en sträng med namnet
jsonString
. - Beräknar ett genomsnittsbetyg för objekt i en
Students
matris som har enGrade
egenskap. - Tilldelar ett standardbetyg på 70 för elever som inte har ett betyg.
- Skapar instansen
JsonDocument
i enusing
-instruktion eftersomJsonDocument
implementerarIDisposable
. När enJsonDocument
instans har avyttrats förlorar du även åtkomsten till alla dessJsonElement
instanser. Om du vill behålla åtkomsten till enJsonElement
instans gör du en kopia av den innan den överordnadeJsonDocument
instansen tas bort. Om du vill göra en kopia anropar du JsonElement.Clone. Mer information finns i JsonDocument is IDisposable (JsonDocument is IDisposable).
Föregående exempelkod räknar eleverna genom att öka en count
variabel med varje iteration. Ett alternativ är att anropa GetArrayLength, enligt följande exempel:
double sum = 0;
int count = 0;
using (JsonDocument document = JsonDocument.Parse(jsonString))
{
JsonElement root = document.RootElement;
JsonElement studentsElement = root.GetProperty("Students");
count = studentsElement.GetArrayLength();
foreach (JsonElement student in studentsElement.EnumerateArray())
{
if (student.TryGetProperty("Grade", out JsonElement gradeElement))
{
sum += gradeElement.GetDouble();
}
else
{
sum += 70;
}
}
}
double average = sum / count;
Console.WriteLine($"Average grade : {average}");
Dim sum As Double = 0
Dim count As Integer = 0
Using document As JsonDocument = JsonDocument.Parse(jsonString)
Dim root As JsonElement = document.RootElement
Dim studentsElement As JsonElement = root.GetProperty("Students")
count = studentsElement.GetArrayLength()
For Each student As JsonElement In studentsElement.EnumerateArray()
Dim gradeElement As JsonElement = Nothing
If student.TryGetProperty("Grade", gradeElement) Then
sum += gradeElement.GetDouble()
Else
sum += 70
End If
Next
End Using
Dim average As Double = sum / count
Console.WriteLine($"Average grade : {average}")
Här är ett exempel på JSON som den här koden bearbetar:
{
"Class Name": "Science",
"Teacher\u0027s Name": "Jane",
"Semester": "2019-01-01",
"Students": [
{
"Name": "John",
"Grade": 94.3
},
{
"Name": "James",
"Grade": 81.0
},
{
"Name": "Julia",
"Grade": 91.9
},
{
"Name": "Jessica",
"Grade": 72.4
},
{
"Name": "Johnathan"
}
],
"Final": true
}
Ett liknande exempel som använder JsonNode
i stället för JsonDocument
finns i JsonNode average grade example (Genomsnittligt betygsexempel för JsonNode).
Så här söker du efter underelement i JsonDocument och JsonElement
Sökningar på JsonElement
kräver en sekventiell sökning av egenskaperna och är därför relativt långsamma (till exempel när du använder TryGetProperty
). System.Text.Json är utformad för att minimera den inledande parsningstiden i stället för uppslagstiden. Använd därför följande metoder för att optimera prestanda vid sökning via ett JsonDocument
objekt:
- Använd inbyggda uppräknare (EnumerateArray och EnumerateObject) i stället för att göra egna indexering eller loopar.
- Gör inte en sekventiell sökning på det hela taget
JsonDocument
genom varje egenskap med hjälpRootElement
av . Sök i stället efter kapslade JSON-objekt baserat på den kända strukturen för JSON-data. Till exempel letar de föregående kodexemplen efter enGrade
egenskap iStudent
objekt genom att loopa igenom objektenStudent
och hämta värdetGrade
för var och en, i stället för att söka igenom allaJsonElement
objekt som sökerGrade
efter egenskaper. Om du gör det senare skulle det leda till onödiga passeringar över samma data.
Jämför JsonElements
Om du vill jämföra två JsonElement
objekt för likhet, inklusive deras underordnade element, använder du JsonElement.DeepEquals(JsonElement, JsonElement) metoden.
JsonElement left = JsonDocument.Parse("10e-3").RootElement;
JsonElement right = JsonDocument.Parse("0.01").RootElement;
bool equal = JsonElement.DeepEquals(left, right);
Console.WriteLine(equal); // True.
Använd JsonDocument
för att skriva JSON
I följande exempel visas hur du skriver JSON från en JsonDocument:
string jsonString = File.ReadAllText(inputFileName);
var writerOptions = new JsonWriterOptions
{
Indented = true
};
var documentOptions = new JsonDocumentOptions
{
CommentHandling = JsonCommentHandling.Skip
};
using FileStream fs = File.Create(outputFileName);
using var writer = new Utf8JsonWriter(fs, options: writerOptions);
using JsonDocument document = JsonDocument.Parse(jsonString, documentOptions);
JsonElement root = document.RootElement;
if (root.ValueKind == JsonValueKind.Object)
{
writer.WriteStartObject();
}
else
{
return;
}
foreach (JsonProperty property in root.EnumerateObject())
{
property.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
Dim jsonString As String = File.ReadAllText(inputFileName)
Dim writerOptions As JsonWriterOptions = New JsonWriterOptions With {
.Indented = True
}
Dim documentOptions As JsonDocumentOptions = New JsonDocumentOptions With {
.CommentHandling = JsonCommentHandling.Skip
}
Dim fs As FileStream = File.Create(outputFileName)
Dim writer As Utf8JsonWriter = New Utf8JsonWriter(fs, options:=writerOptions)
Dim document As JsonDocument = JsonDocument.Parse(jsonString, documentOptions)
Dim root As JsonElement = document.RootElement
If root.ValueKind = JsonValueKind.[Object] Then
writer.WriteStartObject()
Else
Return
End If
For Each [property] As JsonProperty In root.EnumerateObject()
[property].WriteTo(writer)
Next
writer.WriteEndObject()
writer.Flush()
Koden ovan:
- Läser en JSON-fil, läser in data i en
JsonDocument
, och skriver formaterad (ganska utskriven) JSON till en fil. - Används JsonDocumentOptions för att ange att kommentarer i JSON-indata tillåts men ignoreras.
- När du är klar anropar Flush du författaren. Ett alternativ är att låta skrivaren rensa automatiskt när den tas bort.
Här är ett exempel på JSON-indata som ska bearbetas av exempelkoden:
{"Class Name": "Science","Teacher's Name": "Jane","Semester": "2019-01-01","Students": [{"Name": "John","Grade": 94.3},{"Name": "James","Grade": 81.0},{"Name": "Julia","Grade": 91.9},{"Name": "Jessica","Grade": 72.4},{"Name": "Johnathan"}],"Final": true}
Resultatet är följande ganska utskrivna JSON-utdata:
{
"Class Name": "Science",
"Teacher\u0027s Name": "Jane",
"Semester": "2019-01-01",
"Students": [
{
"Name": "John",
"Grade": 94.3
},
{
"Name": "James",
"Grade": 81.0
},
{
"Name": "Julia",
"Grade": 91.9
},
{
"Name": "Jessica",
"Grade": 72.4
},
{
"Name": "Johnathan"
}
],
"Final": true
}
JsonDocument är IDisposable
JsonDocument
skapar en minnesintern vy över data till en poolbuffert. JsonDocument
Därför implementerar IDisposable
och måste typen användas i ett using
block.
Returnera endast en JsonDocument
från ditt API om du vill överföra livstidsägarskap och ta ansvar för anroparen. I de flesta scenarier är det inte nödvändigt. Om anroparen behöver arbeta med hela JSON-dokumentet returnerar du Clone för RootElement, som är en JsonElement. Om anroparen behöver arbeta med ett visst element i JSON-dokumentet returnerar Clone du den JsonElement. Om du returnerar RootElement
eller ett underelement direkt utan att göra ett Clone
kan anroparen inte komma åt det returnerade JsonElement
efter JsonDocument
att det som äger det har avyttrats.
Här är ett exempel som kräver att du gör en Clone
:
public JsonElement LookAndLoad(JsonElement source)
{
string json = File.ReadAllText(source.GetProperty("fileName").GetString());
using (JsonDocument doc = JsonDocument.Parse(json))
{
return doc.RootElement.Clone();
}
}
Föregående kod förväntar sig en JsonElement
som innehåller en fileName
egenskap. Den öppnar JSON-filen och skapar en JsonDocument
. Metoden förutsätter att anroparen vill arbeta med hela dokumentet, så den returnerar Clone
för RootElement
.
Om du får ett JsonElement
och returnerar ett underelement är det inte nödvändigt att returnera ett Clone
av delelementet. Uppringaren ansvarar för att hålla liv i den JsonDocument
som den införda JsonElement
tillhör. Till exempel:
public JsonElement ReturnFileName(JsonElement source)
{
return source.GetProperty("fileName");
}
JsonDocument
med JsonSerializerOptions
Du kan använda JsonSerializer
för att serialisera och deserialisera en instans av JsonDocument
. Implementeringen för att läsa och skriva JsonDocument
instanser med hjälp JsonSerializer
av är dock en omslutning över JsonDocument.ParseValue(Utf8JsonReader) och JsonDocument.WriteTo(Utf8JsonWriter). Den här omslutningen vidarebefordrar inte några JsonSerializerOptions
(serialiserarfunktioner) till Utf8JsonReader
eller Utf8JsonWriter
. Om du till exempel ställer in JsonSerializerOptions.DefaultIgnoreCondition på WhenWritingNull och anropar JsonSerializer
med en överlagring som tar JsonSerializerOptions
ignoreras inte null-egenskaper.
I följande exempel visas resultatet av att använda metoder som tar en JsonSerializerOptions
parameter och serialiserar en JsonDocument
instans:
using System.Text.Json;
using System.Text.Json.Serialization;
namespace JsonDocumentWithJsonSerializerOptions;
public class Program
{
public static void Main()
{
Person person = new() { Name = "Nancy" };
// Default serialization - Address property included with null token.
// Output: {"Name":"Nancy","Address":null}
string personJsonWithNull = JsonSerializer.Serialize(person);
Console.WriteLine(personJsonWithNull);
// Serialize and ignore null properties - null Address property is omitted
// Output: {"Name":"Nancy"}
JsonSerializerOptions options = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
string personJsonWithoutNull = JsonSerializer.Serialize(person, options);
Console.WriteLine(personJsonWithoutNull);
// Ignore null properties doesn't work when serializing JsonDocument instance
// by using JsonSerializer.
// Output: {"Name":"Nancy","Address":null}
JsonDocument? personJsonDocument = JsonSerializer.Deserialize<JsonDocument>(personJsonWithNull);
personJsonWithNull = JsonSerializer.Serialize(personJsonDocument, options);
Console.WriteLine(personJsonWithNull);
}
}
public class Person
{
public string? Name { get; set; }
public string? Address { get; set; }
}
Om du behöver funktioner JsonSerializerOptions
i använder JsonSerializer
du med starkt skrivna mål (till exempel Person
klassen i det här exemplet) i stället JsonDocument
för .