Share via


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. Het JsonElement 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. De JsonDocument 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 een Grade 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 van JsonArray.

JsonNode met JsonSerializerOptions

U kunt een JsonSerializer exemplaar JsonNodevan . 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 JsonNodevan .

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 een Grade eigenschap.
  • Hiermee wordt een standaardcijfer van 70 toegewezen voor leerlingen/studenten die geen cijfer hebben.
  • Hiermee maakt u het JsonDocument exemplaar in een using instructie omdat JsonDocument deze wordt geïmplementeerd IDisposable. Nadat een JsonDocument exemplaar is verwijderd, hebt u ook geen toegang meer tot alle JsonElement exemplaren. Als u de toegang tot een JsonElement exemplaar wilt behouden, maakt u er een kopie van voordat het bovenliggende JsonDocument 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 JsonDocumentJsonNode 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 van RootElement. 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 in Student objecten door de Student objecten te doorlopen en de waarde voor elk object op te halen, in plaats van Grade door alle JsonElement 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 JsonDocumenten 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 Clonesubelement 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 RootElementdocument 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 JsonDocumentvan . 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 JsonSerializerOptionsnodig hebt, gebruikt JsonSerializer u met sterk getypte doelen (zoals de Person klasse in dit voorbeeld) in plaats JsonDocumentvan .

Zie ook