Jak używać modelu obiektu dokumentu JSON w programie System.Text.Json
W tym artykule pokazano, jak używać modelu obiektów dokumentów JSON (DOM) do losowego dostępu do danych w ładunku JSON.
Opcje modelu DOM w formacie JSON
Praca z dom jest alternatywą dla deserializacji w JsonSerializer przypadku:
- Nie masz typu do deserializacji.
- Otrzymany kod JSON nie ma stałego schematu i musi być sprawdzany, aby wiedzieć, co zawiera.
System.Text.Json
Udostępnia dwa sposoby tworzenia modelu DOM w formacie JSON:
JsonDocument zapewnia możliwość tworzenia modelu DOM tylko do odczytu przy użyciu polecenia
Utf8JsonReader
. Dostęp do elementów JSON, które tworzą ładunek, można uzyskać za pośrednictwem JsonElement typu . TypJsonElement
udostępnia moduły wyliczania tablic i obiektów wraz z interfejsami API w celu konwertowania tekstu JSON na typowe typy platformy .NET.JsonDocument
uwidacznia RootElement właściwość. Aby uzyskać więcej informacji, zobacz Używanie narzędzia JsonDocument w dalszej części tego artykułu.JsonNode i klasy, które pochodzą z niego w System.Text.Json.Nodes przestrzeni nazw, zapewniają możliwość tworzenia modyfikowalnego modelu DOM. Dostęp do elementów JSON, które tworzą ładunek, można uzyskać za pośrednictwem JsonNodetypów , JsonObject, JsonArray, JsonValuei JsonElement . Aby uzyskać więcej informacji, zobacz Używanie
JsonNode
w dalszej części tego artykułu.
Podczas wybierania między elementami JsonDocument
i JsonNode
należy wziąć pod uwagę następujące czynniki:
- Dom
JsonNode
można zmienić po jego utworzeniu. DomJsonDocument
jest niezmienny. - Dom
JsonDocument
zapewnia szybszy dostęp do danych.
Korzystanie z polecenia JsonNode
W poniższym przykładzie pokazano, jak używać JsonNode i innych typów w przestrzeni nazw do System.Text.Json.Nodes :
- Tworzenie modelu DOM na podstawie ciągu JSON
- Zapis JSON z modelu DOM.
- Pobierz wartość, obiekt lub tablicę z modelu 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"
}
}
Tworzenie elementu DOM JsonNode z inicjatorami obiektów i wprowadzanie zmian
W poniższym przykładzie pokazano, jak:
- Utwórz dom przy użyciu inicjatorów obiektów.
- Wprowadź zmiany w modelu 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
// }
// }
//}
}
}
Deserializowanie podsekcji ładunku JSON
W poniższym przykładzie pokazano, jak za pomocą narzędzia JsonNode przejść do podsekcji drzewa JSON i deserializować pojedynczą wartość, typ niestandardowy lub tablicę z tej podsekcji.
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
}
}
Przykład średniej klasy JsonNode
Poniższy przykład wybiera tablicę JSON zawierającą wartości całkowite i oblicza średnią wartość:
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
Powyższy kod ma następujące działanie:
- Oblicza średnią ocenę dla obiektów w
Students
tablicy, która maGrade
właściwość. - Przypisuje domyślną ocenę 70 dla uczniów, którzy nie mają klasy.
- Pobiera liczbę uczniów z
Count
właściwościJsonArray
.
JsonNode
Z JsonSerializerOptions
Można użyć JsonSerializer
do serializacji i deserializacji wystąpienia klasy JsonNode
. Jeśli jednak używasz przeciążenia, które przyjmuje JsonSerializerOptions
, wystąpienie opcji jest używane tylko do pobierania konwerterów niestandardowych. Inne funkcje wystąpienia opcji nie są używane. Jeśli na przykład zostanie ustawiona JsonSerializerOptions.DefaultIgnoreConditionWhenWritingNull wartość i wywołana JsonSerializer
z przeciążeniem, które przyjmuje JsonSerializerOptions
, właściwości null nie zostaną zignorowane.
To samo ograniczenie dotyczy JsonNode
metod, które przyjmują JsonSerializerOptions
parametr : WriteTo(Utf8JsonWriter, JsonSerializerOptions) i ToJsonString(JsonSerializerOptions). Te interfejsy API używają JsonSerializerOptions
tylko do pobierania konwerterów niestandardowych.
Poniższy przykład ilustruje wynik użycia metod, które przyjmują JsonSerializerOptions
parametr i serializują JsonNode
wystąpienie:
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; }
}
Jeśli potrzebujesz funkcji JsonSerializerOptions
innych niż konwertery niestandardowe, użyj z JsonSerializer
silnie typinymi obiektami docelowymi (takimi jak Person
klasa w tym przykładzie), a nie JsonNode
.
Korzystanie z polecenia JsonDocument
W poniższym przykładzie pokazano, jak używać JsonDocument klasy do losowego dostępu do danych w ciągu JSON:
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}")
Powyższy kod ma następujące działanie:
- Przyjęto założenie, że kod JSON do analizy znajduje się w ciągu o nazwie
jsonString
. - Oblicza średnią ocenę dla obiektów w
Students
tablicy, która maGrade
właściwość. - Przypisuje domyślną ocenę 70 dla uczniów, którzy nie mają klasy.
JsonDocument
Tworzy wystąpienie w instrukcjiusing
, ponieważJsonDocument
implementujeIDisposable
element . Po usunięciuJsonDocument
wystąpienia utracisz również dostęp do wszystkich jegoJsonElement
wystąpień. Aby zachować dostęp doJsonElement
wystąpienia, utwórz jego kopię przed likwidacją wystąpienia nadrzędnegoJsonDocument
. Aby utworzyć kopię, wywołaj metodę JsonElement.Clone. Aby uzyskać więcej informacji, zobacz JsonDocument is IDisposable (Dokument JsonDocument to IDisposable).
Powyższy przykładowy kod zlicza uczniów, zwiększając zmienną count
z każdą iterację. Alternatywą jest wywołanie metody GetArrayLength, jak pokazano w poniższym przykładzie:
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}")
Oto przykład kodu JSON, który przetwarza ten kod:
{
"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
}
Aby zapoznać się z podobnym przykładem, który używa JsonNode
zamiast elementu , zobacz przykład średniej JsonDocument
klasy JsonNode.
Jak wyszukiwać elementy podrzędne JsonDocument i JsonElement
JsonElement
Wyszukiwanie wymaga sekwencyjnego wyszukiwania właściwości i dlatego jest stosunkowo powolne (na przykład w przypadku używania metody TryGetProperty
). System.Text.Json program został zaprojektowany tak, aby zminimalizować czas analizy początkowej, a nie czas wyszukiwania. W związku z tym należy użyć następujących metod optymalizacji wydajności podczas wyszukiwania JsonDocument
obiektu:
- Użyj wbudowanych modułów wyliczających (EnumerateArray i EnumerateObject), zamiast wykonywać własne indeksowanie lub pętle.
- Nie należy wykonywać sekwencyjnego wyszukiwania dla całej
JsonDocument
całej właściwości za pomocą metodyRootElement
. Zamiast tego wyszukaj zagnieżdżone obiekty JSON na podstawie znanej struktury danych JSON. Na przykład powyższe przykłady kodu wyszukująGrade
właściwość wStudent
obiektach, tworząc pętlę przezStudent
obiekty i uzyskując wartośćGrade
dla każdego z nich, zamiast przeszukiwać wszystkieJsonElement
obiekty wyszukująceGrade
właściwości. Wykonanie tych ostatnich spowoduje niepotrzebne przekazanie tych samych danych.
Użyj JsonDocument
polecenia , aby zapisać kod JSON
W poniższym przykładzie pokazano, jak napisać kod JSON z pliku 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()
Powyższy kod ma następujące działanie:
- Odczytuje plik JSON, ładuje dane do
JsonDocument
pliku i zapisuje formatowane (dość drukowane) dane JSON do pliku. - Umożliwia JsonDocumentOptions określenie, że komentarze w wejściowym formacie JSON są dozwolone, ale ignorowane.
- Po zakończeniu wywołania Flush modułu zapisywania. Alternatywą jest pozwolić modułowi zapisywania na automatyczne opróżnienie, gdy zostanie usunięte.
Oto przykład danych wejściowych JSON, które mają być przetwarzane przez przykładowy kod:
{"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}
Wynik jest następującymi dość drukowanymi danymi wyjściowymi JSON:
{
"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 to IDisposable
JsonDocument
tworzy widok danych w pamięci w buforze w puli. W związku z tym JsonDocument
typ implementuje IDisposable
i musi być używany wewnątrz using
bloku.
Zwróć JsonDocument
element z interfejsu API tylko wtedy, gdy chcesz przenieść własność okresu istnienia i usunąć odpowiedzialność za obiekt wywołujący. W większości scenariuszy nie jest to konieczne. Jeśli obiekt wywołujący musi pracować z całym dokumentem JSON, zwróć element CloneRootElement, czyli JsonElement. Jeśli obiekt wywołujący musi pracować z określonym elementem w dokumencie JSON, zwróć Clone ten JsonElementelement . Jeśli zwracasz element podrzędny RootElement
lub bezpośrednio bez tworzenia Clone
elementu , obiekt wywołujący nie będzie mógł uzyskać dostępu do zwróconego JsonElement
elementu po usunięciu elementu będącego JsonDocument
właścicielem.
Oto przykład, który wymaga utworzenia elementu Clone
:
public JsonElement LookAndLoad(JsonElement source)
{
string json = File.ReadAllText(source.GetProperty("fileName").GetString());
using (JsonDocument doc = JsonDocument.Parse(json))
{
return doc.RootElement.Clone();
}
}
Powyższy kod oczekuje JsonElement
właściwości , która zawiera fileName
właściwość . Spowoduje to otwarcie pliku JSON i utworzenie pliku JsonDocument
. Metoda zakłada, że obiekt wywołujący chce pracować z całym dokumentem, więc zwraca wartość Clone
.RootElement
Jeśli otrzymasz element JsonElement
i zwraca element podrzędny, nie jest konieczne zwrócenie elementu Clone
podrzędnego. Wywołujący jest odpowiedzialny za utrzymanie przy życiu JsonDocument
, do którego należy przekazany JsonElement
element. Na przykład:
public JsonElement ReturnFileName(JsonElement source)
{
return source.GetProperty("fileName");
}
JsonDocument
Z JsonSerializerOptions
Można użyć JsonSerializer
do serializacji i deserializacji wystąpienia klasy JsonDocument
. Jednak implementacja odczytywania i zapisywania JsonDocument
wystąpień przy JsonSerializer
użyciu jest otoką obiektów JsonDocument.ParseValue(Utf8JsonReader) i JsonDocument.WriteTo(Utf8JsonWriter). Ta otoka nie przekazuje żadnych JsonSerializerOptions
(funkcji serializatora) do Utf8JsonReader
lub Utf8JsonWriter
. Jeśli na przykład zostanie ustawiona JsonSerializerOptions.DefaultIgnoreConditionWhenWritingNull wartość i wywołana JsonSerializer
z przeciążeniem, które przyjmuje JsonSerializerOptions
, właściwości null nie zostaną zignorowane.
Poniższy przykład ilustruje wynik użycia metod, które przyjmują JsonSerializerOptions
parametr i serializują JsonDocument
wystąpienie:
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; }
}
Jeśli potrzebujesz funkcji JsonSerializerOptions
, należy używać JsonSerializer
z silnie typinymi obiektami docelowymi (takimi jak Person
klasa w tym przykładzie) zamiast JsonDocument
.