Sdílet prostřednictvím


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. Tento JsonElement typ poskytuje maticové a objektové enumerátory spolu s rozhraními API pro převod textu JSON na běžné typy .NET. JsonDocumentRootElement 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. Objekt JsonDocument 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 v using příkazu, protože JsonDocument implementuje IDisposable. JsonDocument Po odstranění instance ztratíte přístup ke všem jeho JsonElement instancím. Pokud chcete zachovat přístup k JsonElement 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 JsonDocumentpouží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 v Student objektech tak, že prochází Student objekty a získá hodnotu Grade pro každý z nich, a ne prohledávají všechny JsonElement 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 JsonDocumentsouboru 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

Viz také