Een JSON-documentobjectmodel gebruiken in System.Text.Json
In dit artikel wordt beschreven hoe u een JSON-documentobjectmodel (DOM) gebruikt voor willekeurige toegang tot gegevens in een JSON-nettolading.
JSON DOM-opties
Werken met een DOM is een alternatief voor deserialisatie waarbij JsonSerializer :
- U hebt geen type om te deserialiseren in.
- De JSON die u ontvangt, heeft geen vast schema en moet worden geïnspecteerd om te weten wat deze bevat.
System.Text.Json
biedt twee manieren om een JSON DOM te bouwen:
JsonDocument biedt de mogelijkheid om een alleen-lezen DOM te bouwen met behulp van
Utf8JsonReader
. De JSON-elementen die de nettolading vormen, kunnen worden geopend via het JsonElement type. HetJsonElement
type biedt matrix- en object-opsommingstekens, samen met API's om JSON-tekst te converteren naar algemene .NET-typen.JsonDocument
maakt een RootElement eigenschap beschikbaar. Zie JsonDocument verderop in dit artikel gebruiken voor meer informatie.JsonNode en de klassen die daaruit zijn afgeleid in de System.Text.Json.Nodes naamruimte bieden de mogelijkheid om een veranderlijke DOM te maken. De JSON-elementen die de nettolading opstellen, kunnen worden geopend via de JsonNodetypen , JsonObjectJsonArrayen JsonElement JsonValuetypen. Zie Gebruik
JsonNode
verderop in dit artikel voor meer informatie.
Houd rekening met de volgende factoren bij het kiezen tussen JsonDocument
en JsonNode
:
- De
JsonNode
DOM kan worden gewijzigd nadat deze is gemaakt. DeJsonDocument
DOM is onveranderbaar. - De
JsonDocument
DOM biedt snellere toegang tot de gegevens.
JsonNode
gebruiken
In het volgende voorbeeld ziet u hoe u en de andere typen in de System.Text.Json.Nodes naamruimte kunt gebruiken JsonNode om:
- Een DOM maken op basis van een JSON-tekenreeks
- Schrijf JSON vanuit een DOM.
- Een waarde, object of matrix ophalen uit een 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"
}
}
Een JsonNode DOM maken met object initializers en wijzigingen aanbrengen
In het volgende voorbeeld ziet u hoe u:
- Een DOM maken met behulp van object initializers.
- Breng wijzigingen aan in een 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
// }
// }
//}
}
}
Subsecties van een JSON-nettolading deserialiseren
In het volgende voorbeeld ziet u hoe u JsonNode gebruikt om naar een subsectie van een JSON-structuur te navigeren en één waarde, een aangepast type of een matrix uit die subsectie te deserialiseren.
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
}
}
Voorbeeld van gemiddelde cijfer voor JsonNode
In het volgende voorbeeld wordt een JSON-matrix geselecteerd die gehele getallen bevat en een gemiddelde waarde berekent:
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
Met de voorgaande code wordt:
- Berekent een gemiddelde cijfer voor objecten in een
Students
matrix met eenGrade
eigenschap. - Hiermee wordt een standaardcijfer van 70 toegewezen voor leerlingen/studenten die geen cijfer hebben.
- Hiermee haalt u het aantal studenten op uit de
Count
eigenschap vanJsonArray
.
JsonNode
met JsonSerializerOptions
U kunt een JsonSerializer
exemplaar JsonNode
van . Als u echter een overbelasting gebruikt die nodig is JsonSerializerOptions
, wordt het exemplaar van de opties alleen gebruikt om aangepaste conversieprogramma's op te halen. Andere functies van het exemplaar van opties worden niet gebruikt. Als u bijvoorbeeld instelt JsonSerializerOptions.DefaultIgnoreCondition op WhenWritingNull en aanroept JsonSerializer
met een overbelasting die nodig is JsonSerializerOptions
, worden null-eigenschappen niet genegeerd.
Dezelfde beperking geldt voor de JsonNode
methoden die een JsonSerializerOptions
parameter gebruiken: WriteTo(Utf8JsonWriter, JsonSerializerOptions) en ToJsonString(JsonSerializerOptions). Deze API's gebruiken JsonSerializerOptions
alleen om aangepaste conversieprogramma's op te halen.
In het volgende voorbeeld ziet u het resultaat van het gebruik van methoden die een JsonSerializerOptions
parameter gebruiken en een JsonNode
exemplaar serialiseren:
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; }
}
Als u andere functies JsonSerializerOptions
dan aangepaste conversieprogramma's nodig hebt, gebruikt JsonSerializer
u met sterk getypte doelen (zoals de Person
klasse in dit voorbeeld) in plaats JsonNode
van .
Eigenschapsvolgorde bewerken
JsonObject is een van de elementen in de nettolading van een JsonNode, en vertegenwoordigt een veranderlijk JSON-object. Hoewel het type is gemodelleerd als een IDictionary<string, JsonNode>
, waarbij elke vermelding een eigenschap van het object is, wordt een impliciete eigenschapsvolgorde ingekapseld. API's zoals Insert(Int32, String, JsonNode) en RemoveAt(Int32) modelleren het type echter als een geordende woordenlijst door items in een specifieke index in te voegen en te verwijderen. Met deze API's kunnen wijzigingen worden aangebracht in objectexemplaren die rechtstreeks invloed kunnen hebben op de eigenschapsvolgorde.
De volgende code toont een voorbeeld van het toevoegen of verplaatsen van een specifieke eigenschap aan het begin van het object.
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;
}
JsonNodes vergelijken
Gebruik de JsonNode.DeepEquals(JsonNode, JsonNode) methode om twee JsonNode
objecten te vergelijken voor gelijkheid, inclusief hun onderliggende elementen.
JsonDocument
gebruiken
In het volgende voorbeeld ziet u hoe u de JsonDocument klasse gebruikt voor willekeurige toegang tot gegevens in een JSON-tekenreeks:
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}")
Met de voorgaande code wordt:
- Gaat ervan uit dat de JSON die moet worden geanalyseerd zich in een tekenreeks bevindt met de naam
jsonString
. - Berekent een gemiddelde cijfer voor objecten in een
Students
matrix met eenGrade
eigenschap. - Hiermee wordt een standaardcijfer van 70 toegewezen voor leerlingen/studenten die geen cijfer hebben.
- Hiermee maakt u het
JsonDocument
exemplaar in eenusing
instructie omdatJsonDocument
deze wordt geïmplementeerdIDisposable
. Nadat eenJsonDocument
exemplaar is verwijderd, hebt u ook geen toegang meer tot alleJsonElement
exemplaren. Als u de toegang tot eenJsonElement
exemplaar wilt behouden, maakt u er een kopie van voordat het bovenliggendeJsonDocument
exemplaar wordt verwijderd. Als u een kopie wilt maken, belt u JsonElement.Clone. Zie JsonDocument is IDisposable voor meer informatie.
Met de voorgaande voorbeeldcode worden leerlingen/studenten geteld door een count
variabele met elke iteratie te verhogen. Een alternatief is om aan te roepen GetArrayLength, zoals wordt weergegeven in het volgende voorbeeld:
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}")
Hier volgt een voorbeeld van de JSON die door deze code wordt verwerkt:
{
"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
}
Zie voor een vergelijkbaar voorbeeld dat in JsonNode
plaats van JsonDocument
JsonNode het gemiddelde cijfervoorbeeld gebruikt.
Een JsonDocument en JsonElement doorzoeken op subelementen
JsonElement
Zoekopdrachten vereisen een sequentiële zoekopdracht van de eigenschappen en zijn daarom relatief traag (bijvoorbeeld bij gebruikTryGetProperty
). System.Text.Json is ontworpen om de initiële parseringstijd te minimaliseren in plaats van opzoektijd. Gebruik daarom de volgende methoden om de prestaties te optimaliseren bij het doorzoeken van een JsonDocument
object:
- Gebruik de ingebouwde enumerators (EnumerateArray en EnumerateObject) in plaats van uw eigen indexering of lussen uit te voeren.
- Voer geen sequentiële zoekopdrachten uit op het geheel
JsonDocument
door elke eigenschap met behulp vanRootElement
. Zoek in plaats daarvan op geneste JSON-objecten op basis van de bekende structuur van de JSON-gegevens. De voorgaande codevoorbeelden zoeken bijvoorbeeld naar een eigenschap inStudent
objecten door deStudent
objecten te doorlopen en de waarde voor elk object op te halen, in plaats vanGrade
door alleJsonElement
objecten te zoeken die naar eigenschappen zoekenGrade
.Grade
Als u dit laatste doet, leidt dit ertoe dat dezelfde gegevens onnodig worden doorgegeven.
JsonElements vergelijken
Gebruik de JsonElement.DeepEquals(JsonElement, JsonElement) methode om twee JsonElement
objecten te vergelijken voor gelijkheid, inclusief hun onderliggende elementen.
JsonElement left = JsonDocument.Parse("10e-3").RootElement;
JsonElement right = JsonDocument.Parse("0.01").RootElement;
bool equal = JsonElement.DeepEquals(left, right);
Console.WriteLine(equal); // True.
Gebruiken JsonDocument
om JSON te schrijven
In het volgende voorbeeld ziet u hoe u JSON schrijft vanuit een 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()
Met de voorgaande code wordt:
- Leest een JSON-bestand, laadt de gegevens in een
JsonDocument
en schrijft opgemaakte (mooi afgedrukte) JSON naar een bestand. - Hiermee JsonDocumentOptions geeft u op dat opmerkingen in de invoer-JSON zijn toegestaan, maar genegeerd.
- Wanneer u klaar bent, roept Flush u de schrijver aan. Een alternatief is om de schrijver automatisch te laten leegmaken wanneer deze wordt verwijderd.
Hier volgt een voorbeeld van JSON-invoer die moet worden verwerkt door de voorbeeldcode:
{"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}
Het resultaat is de volgende mooie JSON-uitvoer:
{
"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 is IDisposable
JsonDocument
bouwt een in-memory weergave van de gegevens in een poolbuffer. Daarom implementeert IDisposable
het JsonDocument
type en moet het in een using
blok worden gebruikt.
Retourneer alleen een JsonDocument
van uw API als u het eigendom van de levensduur wilt overdragen en de verantwoordelijkheid voor de aanroeper wilt verwijderen. In de meeste scenario's is dat niet nodig. Als de beller met het hele JSON-document moet werken, retourneert u de Clone RootElement, een JsonElement. Als de aanroeper met een bepaald element in het JSON-document moet werken, retourneer dan de Clone waarde .JsonElement Als u het RootElement
of een subelement rechtstreeks retourneert zonder een Clone
subelement te maken, heeft de beller geen toegang tot de geretourneerde JsonElement
items nadat het JsonDocument
is verwijderd.
Hier volgt een voorbeeld waarvoor u een Clone
:
public JsonElement LookAndLoad(JsonElement source)
{
string json = File.ReadAllText(source.GetProperty("fileName").GetString());
using (JsonDocument doc = JsonDocument.Parse(json))
{
return doc.RootElement.Clone();
}
}
In de voorgaande code wordt een JsonElement
eigenschap verwacht die een fileName
eigenschap bevat. Het JSON-bestand wordt geopend en er wordt een JsonDocument
. Bij de methode wordt ervan uitgegaan dat de aanroeper met het hele document wil werken, dus wordt de waarde van het Clone
RootElement
document geretourneerd.
Als u een JsonElement
subelement ontvangt en retourneert, hoeft u geen subelement terug te geven Clone
. De beller is verantwoordelijk voor het in leven houden van waartoe JsonDocument
de doorgegeven gebruiker JsonElement
behoort. Voorbeeld:
public JsonElement ReturnFileName(JsonElement source)
{
return source.GetProperty("fileName");
}
JsonDocument
met JsonSerializerOptions
U kunt een JsonSerializer
exemplaar JsonDocument
van . De implementatie voor het lezen en schrijven JsonDocument
van exemplaren met behulp JsonSerializer
van een wrapper is echter een wrapper over de JsonDocument.ParseValue(Utf8JsonReader) en JsonDocument.WriteTo(Utf8JsonWriter). Deze wrapper stuurt geen JsonSerializerOptions
(serialisatiefuncties) door naar Utf8JsonReader
of Utf8JsonWriter
. Als u bijvoorbeeld instelt JsonSerializerOptions.DefaultIgnoreCondition op WhenWritingNull en aanroept JsonSerializer
met een overbelasting die nodig is JsonSerializerOptions
, worden null-eigenschappen niet genegeerd.
In het volgende voorbeeld ziet u het resultaat van het gebruik van methoden die een JsonSerializerOptions
parameter gebruiken en een JsonDocument
exemplaar serialiseren:
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; }
}
Als u functies van JsonSerializerOptions
nodig hebt, gebruikt JsonSerializer
u met sterk getypte doelen (zoals de Person
klasse in dit voorbeeld) in plaats JsonDocument
van .