Jak používat objektový model dokumentu JSON v System.Text.Json
Tento článek ukazuje, jak použít objektový model dokumentu JSON (DOM) pro náhodný přístup k datům v datové části JSON.
Volby JSON DOM
Práce s modelem DOM je alternativou k deserializaci v případech, kdy JsonSerializer :
- Nemáte typ k deserializaci.
- Kód JSON, který obdržíte, nemá pevné schéma a musí se zkontrolovat, abyste věděli, co obsahuje.
System.Text.Json
poskytuje dva způsoby sestavení DOM JSON:
JsonDocument poskytuje možnost vytvořit dom jen pro čtení pomocí
Utf8JsonReader
. K elementům JSON, které tvoří datovou část, je možné přistupovat prostřednictvím JsonElement typu. TentoJsonElement
typ poskytuje maticové a objektové enumerátory spolu s rozhraními API pro převod textu JSON na běžné typy .NET.JsonDocument
RootElement zveřejňuje vlastnost. Další informace najdete v tématu Použití formátu JsonDocument dále v tomto článku.JsonNode a třídy, které jsou z něj odvozeny v System.Text.Json.Nodes oboru názvů, poskytují možnost vytvořit proměnlivý DOM. K elementům JSON, které tvoří datovou část, lze přistupovat prostřednictvím JsonNodeobjektů , JsonObject, JsonValueJsonArraya JsonElement typů. Další informace naleznete v části Použití
JsonNode
dále v tomto článku.
Při volbě mezi JsonDocument
a JsonNode
:
- Po
JsonNode
vytvoření se dá objekt DOM změnit. ObjektJsonDocument
DOM je neměnný. - DOM
JsonDocument
poskytuje rychlejší přístup k datům.
Použití JsonNode
Následující příklad ukazuje, jak používat JsonNode a další typy v System.Text.Json.Nodes oboru názvů pro:
- Vytvoření modelu DOM z řetězce JSON
- Napište JSON z modelu DOM.
- Získá hodnotu, objekt nebo pole 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"
}
}
Vytvoření modelu JSONNode DOM s inicializátory objektů a provádění změn
Následující příklad ukazuje, jak:
- Vytvoření modelu DOM pomocí inicializátorů objektů
- Proveďte změny v objektu 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
// }
// }
//}
}
}
Deserializace pododdílů datové části JSON
Následující příklad ukazuje, jak pomocí JsonNode přejít do pododdílu stromu JSON a deserializovat jednu hodnotu, vlastní typ nebo pole z tohoto pododdílu.
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
}
}
Příklad průměrné známky JsonNode
Následující příklad vybere pole JSON, které obsahuje celočíselné hodnoty a vypočítá průměrnou hodnotu:
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
Předchozí kód:
- Vypočítá průměrnou známku pro objekty v
Students
poli, které majíGrade
vlastnost. - Přiřadí studentům, kteří nemají známku, výchozí známku 70.
- Získá počet studentů z majetku
Count
.JsonArray
JsonNode
s JsonSerializerOptions
Lze použít JsonSerializer
k serializaci a deserializaci instance JsonNode
. Pokud však použijete přetížení, které přebírá JsonSerializerOptions
, instance možností se používá pouze k získání vlastních převaděčů. Jiné funkce instance možností se nepoužívají. Pokud například nastavíte JsonSerializerOptions.DefaultIgnoreCondition WhenWritingNull a zavoláte JsonSerializer
s přetížením, které přebírá JsonSerializerOptions
, vlastnosti null nebudou ignorovány.
Stejné omezení platí pro JsonNode
metody, které přebírají JsonSerializerOptions
parametr: WriteTo(Utf8JsonWriter, JsonSerializerOptions) a ToJsonString(JsonSerializerOptions). Tato rozhraní API používají JsonSerializerOptions
pouze k získání vlastních převaděčů.
Následující příklad znázorňuje výsledek použití metod, které přebírají JsonSerializerOptions
parametr a serializují JsonNode
instanci:
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; }
}
Pokud potřebujete funkce JsonSerializerOptions
jiné než vlastní převaděče, použijte JsonSerializer
místo toho s cíli silného typu (například třídu v tomto příkladuPerson
).JsonNode
Manipulace s pořadím vlastností
JsonObject je jedním z prvků datové části datové JsonNodečásti a představuje proměnlivý objekt JSON. I když je typ modelovaný jako IDictionary<string, JsonNode>
, kde každá položka je vlastnost objektu, zapouzdřuje implicitní pořadí vlastností. Rozhraní API, jako Insert(Int32, String, JsonNode) je a RemoveAt(Int32) efektivně modeluje typ jako seřazený slovník, ale umožňují vkládat a odebírat položky v určitém indexu. Tato rozhraní API umožňují úpravy instancí objektů, které mohou přímo ovlivnit pořadí vlastností.
Následující kód ukazuje příklad přidání nebo přesunutí konkrétní vlastnosti na začátek objektu.
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;
}
Porovnání uzlů JsonNodes
Chcete-li porovnat dva JsonNode
objekty pro rovnost, včetně jejich následnických prvků, použijte metodu JsonNode.DeepEquals(JsonNode, JsonNode) .
Použití JsonDocument
Následující příklad ukazuje, jak použít JsonDocument třídu pro náhodný přístup k datům v řetězci 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}")
Předchozí kód:
- Předpokládá, že json k analýze je v řetězci s názvem
jsonString
. - Vypočítá průměrnou známku pro objekty v
Students
poli, které majíGrade
vlastnost. - Přiřadí studentům, kteří nemají známku, výchozí známku 70.
JsonDocument
Vytvoří instanci vusing
příkazu, protožeJsonDocument
implementujeIDisposable
.JsonDocument
Po odstranění instance ztratíte přístup ke všem jehoJsonElement
instancím. Pokud chcete zachovat přístup kJsonElement
instanci, vytvořte jeho kopii před odstraněním nadřazenéJsonDocument
instance. Chcete-li vytvořit kopii, zavolejte JsonElement.Clone. Další informace najdete v tématu JsonDocument je IDisposable.
Předchozí příklad kódu počítá studenty zvýšením count
proměnné s každou iterací. Alternativou je volání GetArrayLength, jak je znázorněno v následujícím příkladu:
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}")
Tady je příklad kódu JSON, který tento kód zpracovává:
{
"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
}
Podobný příklad, který místo toho JsonDocument
používáJsonNode
, najdete v příkladu průměrné známky JsonNode.
Vyhledání dílčích elementů ve formátu JsonDocument a JsonElement
Hledání vyžaduje JsonElement
sekvenční vyhledávání vlastností, a proto jsou relativně pomalé (například při použití TryGetProperty
). System.Text.Json je navržen tak, aby minimalizoval počáteční čas analýzy místo doby vyhledávání. Proto při vyhledávání prostřednictvím objektu JsonDocument
optimalizujte výkon pomocí následujících přístupů:
- Místo vlastního indexování nebo smyček používejte předdefinované výčty (EnumerateArray a EnumerateObject).
- Neprodávejte postupné vyhledávání v celém objektu
JsonDocument
prostřednictvím každé vlastnosti pomocí .RootElement
Místo toho vyhledejte vnořené objekty JSON na základě známé struktury dat JSON. Například předchozí příklady kódu hledajíGrade
vlastnost vStudent
objektech tak, že procházíStudent
objekty a získá hodnotuGrade
pro každý z nich, a ne prohledávají všechnyJsonElement
objekty, které hledajíGrade
vlastnosti. Pokud byste to udělali, bylo by zbytečné předat stejná data.
Porovnání elementů JsonElements
Chcete-li porovnat dva JsonElement
objekty pro rovnost, včetně jejich následnických prvků, použijte metodu JsonElement.DeepEquals(JsonElement, JsonElement) .
JsonElement left = JsonDocument.Parse("10e-3").RootElement;
JsonElement right = JsonDocument.Parse("0.01").RootElement;
bool equal = JsonElement.DeepEquals(left, right);
Console.WriteLine(equal); // True.
Použití JsonDocument
k zápisu JSON
Následující příklad ukazuje, jak napsat JSON z 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()
Předchozí kód:
- Načte soubor JSON, načte data do
JsonDocument
souboru a zapíše do souboru formátovaný (celkem vytištěný) JSON. - Používá JsonDocumentOptions se k určení, že komentáře ve vstupním formátu JSON jsou povolené, ale budou ignorovány.
- Až budete hotovi, zavolá Flush se na zapisovač. Alternativou je nechat zapisovač automaticky vyprázdnit, když je uvolněn.
Tady je příklad vstupu JSON, který se má zpracovat ukázkovým kódem:
{"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}
Výsledkem je následující poměrně tištěný výstup 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 je IDisposable
JsonDocument
vytvoří zobrazení dat v paměti do vyrovnávací paměti ve fondu. Proto se JsonDocument
typ implementuje IDisposable
a musí být použit uvnitř using
bloku.
Pokud chcete převést vlastnictví životnosti a likvidovat odpovědnost volajícímu, vraťte ho JsonDocument
jenom z vašeho rozhraní API. Ve většině scénářů to není nutné. Pokud volající potřebuje pracovat s celým dokumentem JsonElementJSON, vraťte Clone hodnotu RootElement, což je . Pokud volající potřebuje pracovat s konkrétním prvkem v dokumentu JSON, vraťte Clone ho JsonElement. Pokud vrátíte RootElement
nebo dílčí prvek přímo bez provedení Clone
, volající nebude mít přístup k vráceným JsonElement
prvkům po JsonDocument
jeho odstranění.
Tady je příklad, který vyžaduje, abyste udělali Clone
:
public JsonElement LookAndLoad(JsonElement source)
{
string json = File.ReadAllText(source.GetProperty("fileName").GetString());
using (JsonDocument doc = JsonDocument.Parse(json))
{
return doc.RootElement.Clone();
}
}
Předchozí kód očekává JsonElement
, že obsahuje fileName
vlastnost. Otevře soubor JSON a vytvoří .JsonDocument
Metoda předpokládá, že volající chce pracovat s celým dokumentem, takže vrátí Clone
hodnotu RootElement
.
Pokud obdržíte JsonElement
dílčí prvek a vracíte ho, není nutné vrátit Clone
dílčí prvek. Volající je zodpovědný za udržování živého JsonDocument
stavu, do kterého předaný JsonElement
patří. Příklad:
public JsonElement ReturnFileName(JsonElement source)
{
return source.GetProperty("fileName");
}
JsonDocument
s JsonSerializerOptions
Lze použít JsonSerializer
k serializaci a deserializaci instance JsonDocument
. Implementace pro čtení a zápis JsonDocument
instancí pomocí je JsonSerializer
však obálka nad JsonDocument.ParseValue(Utf8JsonReader) a JsonDocument.WriteTo(Utf8JsonWriter). Tento obálka nepředává žádné JsonSerializerOptions
(funkce serializátoru) do Utf8JsonReader
nebo Utf8JsonWriter
. Pokud například nastavíte JsonSerializerOptions.DefaultIgnoreCondition WhenWritingNull a zavoláte JsonSerializer
s přetížením, které přebírá JsonSerializerOptions
, vlastnosti null nebudou ignorovány.
Následující příklad znázorňuje výsledek použití metod, které přebírají JsonSerializerOptions
parametr a serializují JsonDocument
instanci:
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; }
}
Pokud potřebujete funkce JsonSerializerOptions
, používejte JsonSerializer
místo toho s cíli silného Person
typu (například třídu v tomto příkladu).JsonDocument