Jak serializować i deserializować (Marshaling and unmarshaling) JSON w programie .NETHow to serialize and deserialize (marshal and unmarshal) JSON in .NET

W tym artykule pokazano, jak używać przestrzeni nazw System.Text.Json do serializacji i deserializacji do i z JavaScript Object Notation (JSON).This article shows how to use the System.Text.Json namespace to serialize and deserialize to and from JavaScript Object Notation (JSON).

Instrukcje i przykładowy kod używają biblioteki bezpośrednio, a nie za pomocą struktury, takiej jak ASP.NET Core.The directions and sample code use the library directly, not through a framework such as ASP.NET Core.

Większość przykładowych kodów serializacji JsonSerializerOptions.WriteIndented, aby true do "DB-Print" pliku JSON (z wcięciem i białym znakiem).Most of the serialization sample code sets JsonSerializerOptions.WriteIndented to true to "pretty-print" the JSON (with indentation and whitespace for human readability). Do użycia w środowisku produkcyjnym zwykle przyjmuje się wartość domyślną false dla tego ustawienia.For production use, you would typically accept the default value of false for this setting.

{1>Przestrzenie nazw<1}Namespaces

Przestrzeń nazw System.Text.Json zawiera wszystkie punkty wejścia i typy główne.The System.Text.Json namespace contains all the entry points and the main types. Przestrzeń nazw System.Text.Json.Serialization zawiera atrybuty i interfejsy API dla zaawansowanych scenariuszy i dostosowań specyficznych dla serializacji i deserializacji.The System.Text.Json.Serialization namespace contains attributes and APIs for advanced scenarios and customization specific to serialization and deserialization. Przykłady kodu przedstawione w tym artykule wymagają using dyrektyw dla jednej lub obu tych przestrzeni nazw:The code examples shown in this article require using directives for one or both of these namespaces:

using System.Text.Json;
using System.Text.Json.Serialization;

Atrybuty z przestrzeni nazw System.Runtime.Serialization nie są obecnie obsługiwane w System.Text.Json.Attributes from the System.Runtime.Serialization namespace aren't currently supported in System.Text.Json.

Pisanie obiektów .NET w formacie JSON (Serializacja)How to write .NET objects to JSON (serialize)

Aby zapisać dane JSON do ciągu lub do pliku, wywołaj metodę JsonSerializer.Serialize.To write JSON to a string or to a file, call the JsonSerializer.Serialize method.

Poniższy przykład tworzy kod JSON jako ciąg:The following example creates JSON as a string:

string jsonString;
jsonString = JsonSerializer.Serialize(weatherForecast);

Poniższy przykład używa kodu synchronicznego do utworzenia pliku JSON:The following example uses synchronous code to create a JSON file:

jsonString = JsonSerializer.Serialize(weatherForecast);
File.WriteAllText(fileName, jsonString);

W poniższym przykładzie jest tworzony plik JSON przy użyciu kodu asynchronicznego:The following example uses asynchronous code to create a JSON file:

using (FileStream fs = File.Create(fileName))
{
    await JsonSerializer.SerializeAsync(fs, weatherForecast);
}

Powyższe przykłady używają wnioskowania typu dla serializowanego typu.The preceding examples use type inference for the type being serialized. Przeciążenie Serialize() przyjmuje parametr typu ogólnego:An overload of Serialize() takes a generic type parameter:

jsonString = JsonSerializer.Serialize<WeatherForecastWithPOCOs>(weatherForecast);

Przykład serializacjiSerialization example

Oto przykładowa Klasa, która zawiera kolekcje i zagnieżdżoną klasę:Here's an example class that contains collections and a nested class:

public class WeatherForecastWithPOCOs
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
    public string SummaryField;
    public IList<DateTimeOffset> DatesAvailable { get; set; }
    public Dictionary<string, HighLowTemps> TemperatureRanges { get; set; }
    public string[] SummaryWords { get; set; }
}

public class HighLowTemps
{
    public int High { get; set; }
    public int Low { get; set; }
}

Dane wyjściowe JSON serializowania wystąpienia poprzedniego typu wyglądają podobnie jak w poniższym przykładzie.The JSON output from serializing an instance of the preceding type looks like the following example. Dane wyjściowe JSON domyślnie są zminimalizowanego:The JSON output is minified by default:

{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot","DatesAvailable":["2019-08-01T00:00:00-07:00","2019-08-02T00:00:00-07:00"],"TemperatureRanges":{"Cold":{"High":20,"Low":-10},"Hot":{"High":60,"Low":20}},"SummaryWords":["Cool","Windy","Humid"]}

W poniższym przykładzie przedstawiono ten sam kod JSON, sformatowany (to jest całkiem wydruk z odstępami i wcięciami):The following example shows the same JSON, formatted (that is, pretty-printed with whitespace and indentation):

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
  "DatesAvailable": [
    "2019-08-01T00:00:00-07:00",
    "2019-08-02T00:00:00-07:00"
  ],
  "TemperatureRanges": {
    "Cold": {
      "High": 20,
      "Low": -10
    },
    "Hot": {
      "High": 60,
      "Low": 20
    }
  },
  "SummaryWords": [
    "Cool",
    "Windy",
    "Humid"
  ]
}

Serializacja do UTF-8Serialize to UTF-8

Aby serializować do UTF-8, wywołaj metodę JsonSerializer.SerializeToUtf8Bytes:To serialize to UTF-8, call the JsonSerializer.SerializeToUtf8Bytes method:

byte[] jsonUtf8Bytes;
var options = new JsonSerializerOptions
{
    WriteIndented = true
};
jsonUtf8Bytes = JsonSerializer.SerializeToUtf8Bytes(weatherForecast, options);

Dostępne jest również Przeciążenie Serialize, które pobiera Utf8JsonWriter.A Serialize overload that takes a Utf8JsonWriter is also available.

Serializacja do UTF-8 jest szybsza o 5-10% niż przy użyciu metod opartych na ciągach.Serializing to UTF-8 is about 5-10% faster than using the string-based methods. Różnica polega na tym, że bajty (w formacie UTF-8) nie muszą być konwertowane na ciągi (UTF-16).The difference is because the bytes (as UTF-8) don't need to be converted to strings (UTF-16).

Zachowanie serializacjiSerialization behavior

Obsługiwane typy to:Supported types include:

  • Elementy podstawowe platformy .NET, które są mapowane na elementy podstawowe języka JavaScript, takie jak typy liczbowe, ciągi i wartości logiczne..NET primitives that map to JavaScript primitives, such as numeric types, strings, and Boolean.
  • Obiekty CLR zdefiniowane przez użytkownika (POCOs).User-defined Plain Old CLR Objects (POCOs).
  • Tablice jednowymiarowe i nieregularne (ArrayName[][]).One-dimensional and jagged arrays (ArrayName[][]).
  • Dictionary<string,TValue>, gdzie TValue jest object, JsonElementlub POCO.Dictionary<string,TValue> where TValue is object, JsonElement, or a POCO.
  • Kolekcje z następujących przestrzeni nazw.Collections from the following namespaces.

Można zaimplementować niestandardowe konwertery w celu obsługi dodatkowych typów lub zapewnienia funkcjonalności, która nie jest obsługiwana przez wbudowane konwertery.You can implement custom converters to handle additional types or to provide functionality that isn't supported by the built-in converters.

Jak odczytywać dane JSON do obiektów .NET (deserializacji)How to read JSON into .NET objects (deserialize)

Aby zdeserializować z ciągu lub pliku, wywołaj metodę JsonSerializer.Deserialize.To deserialize from a string or a file, call the JsonSerializer.Deserialize method.

Poniższy przykład odczytuje dane JSON z ciągu i tworzy wystąpienie klasy WeatherForecast pokazanej wcześniej dla przykładu serializacji:The following example reads JSON from a string and creates an instance of the WeatherForecast class shown earlier for the serialization example:

weatherForecast = JsonSerializer.Deserialize<WeatherForecastWithPOCOs>(jsonString);

Aby zdeserializować z pliku przy użyciu kodu synchronicznego, Odczytaj plik do ciągu, jak pokazano w następującym przykładzie:To deserialize from a file by using synchronous code, read the file into a string, as shown in the following example:

jsonString = File.ReadAllText(fileName);
weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString);

Aby zdeserializować z pliku przy użyciu kodu asynchronicznego, wywołaj metodę DeserializeAsync:To deserialize from a file by using asynchronous code, call the DeserializeAsync method:

using (FileStream fs = File.OpenRead(fileName))
{
    weatherForecast = await JsonSerializer.DeserializeAsync<WeatherForecast>(fs);
}

Deserializacja z UTF-8Deserialize from UTF-8

Aby zdeserializować z UTF-8, wywołaj Przeciążenie JsonSerializer.Deserialize, które pobiera Utf8JsonReader lub ReadOnlySpan<byte>, jak pokazano w poniższych przykładach.To deserialize from UTF-8, call a JsonSerializer.Deserialize overload that takes a Utf8JsonReader or a ReadOnlySpan<byte>, as shown in the following examples. W przykładach założono, że kod JSON znajduje się w tablicy bajtów o nazwie jsonUtf8Bytes.The examples assume the JSON is in a byte array named jsonUtf8Bytes.

var readOnlySpan = new ReadOnlySpan<byte>(jsonUtf8Bytes);
weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(readOnlySpan);
var utf8Reader = new Utf8JsonReader(jsonUtf8Bytes);
weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(ref utf8Reader);

Zachowanie deserializacjiDeserialization behavior

  • Domyślnie w dopasowaniu nazw właściwości rozróżniana jest wielkość liter.By default, property name matching is case-sensitive. Można określić wielkość liter.You can specify case-insensitivity.
  • Jeśli kod JSON zawiera wartość właściwości tylko do odczytu, wartość jest ignorowana i nie jest zgłaszany żaden wyjątek.If the JSON contains a value for a read-only property, the value is ignored and no exception is thrown.
  • Deserializacja do typów referencyjnych bez bezparametrowego konstruktora nie jest obsługiwana.Deserialization to reference types without a parameterless constructor isn't supported.
  • Deserializacja z niezmiennymi obiektami lub właściwościami tylko do odczytu nie jest obsługiwana.Deserialization to immutable objects or read-only properties isn't supported.
  • Domyślnie wyliczenia są obsługiwane jako liczby.By default, enums are supported as numbers. Nazwy wyliczenia można serializować jako ciągi.You can serialize enum names as strings.
  • Pola nie są obsługiwane.Fields aren't supported.
  • Domyślnie komentarze lub końcowe przecinki w wyjątkach throw JSON.By default, comments or trailing commas in the JSON throw exceptions. Można zezwolić na komentarze i końcowe przecinki.You can allow comments and trailing commas.
  • Domyślna głębokość maksymalna to 64.The default maximum depth is 64.

Konwertery niestandardowe można zaimplementować w celu zapewnienia funkcjonalności, która nie jest obsługiwana przez wbudowane konwertery.You can implement custom converters to provide functionality that isn't supported by the built-in converters.

Serializacja do sformatowanego pliku JSONSerialize to formatted JSON

Aby wydrukować dane wyjściowe JSON, ustaw JsonSerializerOptions.WriteIndented na true:To pretty-print the JSON output, set JsonSerializerOptions.WriteIndented to true:

var options = new JsonSerializerOptions
{
    WriteIndented = true,
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);

Oto przykład typu do serializacji i całkiem wydrukowanych danych wyjściowych JSON:Here's an example type to be serialized and pretty-printed JSON output:

public class WeatherForecast
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
}
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot"
}

Dostosowywanie nazw i wartości JSONCustomize JSON names and values

Domyślnie nazwy właściwości i klucze słownika nie są zmieniane w danych wyjściowych JSON, włącznie z wielkością liter.By default, property names and dictionary keys are unchanged in the JSON output, including case. Wartości wyliczeniowe są reprezentowane jako liczby.Enum values are represented as numbers. W tej sekcji wyjaśniono, jak:This section explains how to:

W przypadku innych scenariuszy, które wymagają specjalnej obsługi nazw i wartości właściwości JSON, można zaimplementować konwertery niestandardowe.For other scenarios that require special handling of JSON property names and values, you can implement custom converters.

Dostosowywanie poszczególnych nazw właściwościCustomize individual property names

Aby ustawić nazwę poszczególnych właściwości, Użyj atrybutu [JsonPropertyName] .To set the name of individual properties, use the [JsonPropertyName] attribute.

Oto przykład typu do serializacji i powstającego JSON:Here's an example type to serialize and resulting JSON:

public class WeatherForecastWithPropertyNameAttribute
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
    [JsonPropertyName("Wind")]
    public int WindSpeed { get; set; }
}
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
  "Wind": 35
}

Nazwa właściwości ustawiona przez ten atrybut:The property name set by this attribute:

  • Stosuje się w obu kierunkach dla serializacji i deserializacji.Applies in both directions, for serialization and deserialization.
  • Ma pierwszeństwo przed zasadami nazewnictwa właściwości.Takes precedence over property naming policies.

Użyj notacji CamelCase przypadku dla wszystkich nazw właściwości JSONUse camel case for all JSON property names

Aby użyć notacji CamelCase przypadku dla wszystkich nazw właściwości JSON, ustaw JsonSerializerOptions.PropertyNamingPolicy na JsonNamingPolicy.CamelCase, jak pokazano w następującym przykładzie:To use camel case for all JSON property names, set JsonSerializerOptions.PropertyNamingPolicy to JsonNamingPolicy.CamelCase, as shown in the following example:

var serializeOptions = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions);

Oto przykładowa Klasa do serializacji i danych wyjściowych JSON:Here's an example class to serialize and JSON output:

public class WeatherForecastWithPropertyNameAttribute
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
    [JsonPropertyName("Wind")]
    public int WindSpeed { get; set; }
}
{
  "date": "2019-08-01T00:00:00-07:00",
  "temperatureCelsius": 25,
  "summary": "Hot",
  "Wind": 35
}

Zasady nazewnictwa właściwości przypadku notacji CamelCase:The camel case property naming policy:

  • Dotyczy serializacji i deserializacji.Applies to serialization and deserialization.
  • Jest zastępowany przez atrybuty [JsonPropertyName].Is overridden by [JsonPropertyName] attributes. Jest to dlatego, że nazwa właściwości JSON Wind w przykładzie nie notacji CamelCase wielkości liter.This is why the JSON property name Wind in the example is not camel case.

Użyj niestandardowych zasad nazewnictwa właściwości JSONUse a custom JSON property naming policy

Aby użyć niestandardowych zasad nazewnictwa właściwości JSON, Utwórz klasę pochodzącą z JsonNamingPolicy i Zastąp metodę ConvertName, jak pokazano w następującym przykładzie:To use a custom JSON property naming policy, create a class that derives from JsonNamingPolicy and override the ConvertName method, as shown in the following example:

using System.Text.Json;

namespace SystemTextJsonSamples
{
    public class UpperCaseNamingPolicy : JsonNamingPolicy
    {
        public override string ConvertName(string name) =>
            name.ToUpper();
    }
}

Następnie ustaw właściwość JsonSerializerOptions.PropertyNamingPolicy na wystąpienie klasy zasad nazewnictwa:Then set the JsonSerializerOptions.PropertyNamingPolicy property to an instance of your naming policy class:

var options = new JsonSerializerOptions
{
    PropertyNamingPolicy = new UpperCaseNamingPolicy(),
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);

Oto przykładowa Klasa do serializacji i danych wyjściowych JSON:Here's an example class to serialize and JSON output:

public class WeatherForecastWithPropertyNameAttribute
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
    [JsonPropertyName("Wind")]
    public int WindSpeed { get; set; }
}
{
  "DATE": "2019-08-01T00:00:00-07:00",
  "TEMPERATURECELSIUS": 25,
  "SUMMARY": "Hot",
  "Wind": 35
}

Zasady nazewnictwa właściwości JSON:The JSON property naming policy:

  • Dotyczy serializacji i deserializacji.Applies to serialization and deserialization.
  • Jest zastępowany przez atrybuty [JsonPropertyName].Is overridden by [JsonPropertyName] attributes. Jest to dlatego, że nazwa właściwości JSON Wind w przykładzie nie jest wielką literą.This is why the JSON property name Wind in the example is not upper case.

Klucze słownika przypadku notacji CamelCaseCamel case dictionary keys

Jeśli właściwość obiektu, który ma zostać Zserializowany, jest typu Dictionary<string,TValue>, klucze string można przekonwertować na notacji CamelCase.If a property of an object to be serialized is of type Dictionary<string,TValue>, the string keys can be converted to camel case. W tym celu ustaw DictionaryKeyPolicy na JsonNamingPolicy.CamelCase, jak pokazano w następującym przykładzie:To do that, set DictionaryKeyPolicy to JsonNamingPolicy.CamelCase, as shown in the following example:

var options = new JsonSerializerOptions
{
    DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);

Serializacja obiektu przy użyciu słownika o nazwie TemperatureRanges, który ma pary klucz-wartość, "ColdMinTemp", 20 i "HotMinTemp", 40 spowoduje to wyjście JSON podobne do następującego przykładu:Serializing an object with a dictionary named TemperatureRanges that has key-value pairs "ColdMinTemp", 20 and "HotMinTemp", 40 would result in JSON output like the following example:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
  "TemperatureRanges": {
    "coldMinTemp": 20,
    "hotMinTemp": 40
  }
}

Zasady nazewnictwa przypadków notacji CamelCase dla kluczy słownika mają zastosowanie tylko do serializacji.The camel case naming policy for dictionary keys applies to serialization only. W przypadku deserializacji słownika klucze będą zgodne z plikiem JSON nawet wtedy, gdy dla DictionaryKeyPolicyokreślono JsonNamingPolicy.CamelCase.If you deserialize a dictionary, the keys will match the JSON file even if you specify JsonNamingPolicy.CamelCase for the DictionaryKeyPolicy.

Wyliczenia jako ciągiEnums as strings

Domyślnie wyliczenia są serializowane jako liczby.By default, enums are serialized as numbers. Aby serializować nazwy wyliczenia jako ciągi, użyj JsonStringEnumConverter.To serialize enum names as strings, use the JsonStringEnumConverter.

Załóżmy na przykład, że trzeba serializować następujące klasy, które mają Wyliczenie:For example, suppose you need to serialize the following class that has an enum:

public class WeatherForecastWithEnum
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public Summary Summary { get; set; }
}

public enum Summary
{
    Cold, Cool, Warm, Hot
}

Jeśli podsumowanie jest Hot, domyślnie serializowany kod JSON ma wartość liczbową 3:If the Summary is Hot, by default the serialized JSON has the numeric value 3:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": 3
}

Następujący przykładowy kod serializować nazwy wyliczenia zamiast wartości liczbowych i konwertuje nazwy na notacji CamelCase:The following sample code serializes the enum names instead of the numeric values, and converts the names to camel case:

options = new JsonSerializerOptions();
options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
options.WriteIndented = true;
jsonString = JsonSerializer.Serialize(weatherForecast, options);

Wynikowy kod JSON wygląda podobnie do poniższego przykładu:The resulting JSON looks like the following example:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "hot"
}

Można również deserializować nazwy ciągów wyliczenia, jak pokazano w następującym przykładzie:Enum string names can be deserialized as well, as shown in the following example:

options = new JsonSerializerOptions();
options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
weatherForecast = JsonSerializer.Deserialize<WeatherForecastWithEnum>(jsonString, options);

Wyklucz właściwości z serializacjiExclude properties from serialization

Domyślnie wszystkie właściwości publiczne są serializowane.By default, all public properties are serialized. Jeśli nie chcesz, aby niektóre z nich pojawiały się w danych wyjściowych JSON, masz kilka opcji.If you don't want some of them to appear in the JSON output, you have several options. W tej sekcji wyjaśniono, jak wykluczyć:This section explains how to exclude:

Wyklucz pojedyncze właściwościExclude individual properties

Aby zignorować poszczególne właściwości, Użyj atrybutu [JsonIgnore] .To ignore individual properties, use the [JsonIgnore] attribute.

Oto przykład typu do serializacji i danych wyjściowych JSON:Here's an example type to serialize and JSON output:

public class WeatherForecastWithIgnoreAttribute
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    [JsonIgnore]
    public string Summary { get; set; }
}
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
}

Wyklucz wszystkie właściwości tylko do odczytuExclude all read-only properties

Właściwość jest tylko do odczytu, jeśli zawiera publiczną metodę pobierającą, ale nie do publicznej metody ustawiającej.A property is read-only if it contains a public getter but not a public setter. Aby wykluczyć wszystkie właściwości tylko do odczytu, ustaw JsonSerializerOptions.IgnoreReadOnlyProperties na true, jak pokazano w następującym przykładzie:To exclude all read-only properties, set the JsonSerializerOptions.IgnoreReadOnlyProperties to true, as shown in the following example:

var options = new JsonSerializerOptions
{
    IgnoreReadOnlyProperties = true,
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);

Oto przykład typu do serializacji i danych wyjściowych JSON:Here's an example type to serialize and JSON output:

public class WeatherForecastWithROProperty
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
    public int WindSpeedReadOnly { get; private set; } = 35;
}
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
}

Ta opcja ma zastosowanie tylko do serializacji.This option applies only to serialization. Podczas deserializacji właściwości tylko do odczytu są domyślnie ignorowane.During deserialization, read-only properties are ignored by default.

Wyklucz wszystkie właściwości wartości nullExclude all null value properties

Aby wykluczyć wszystkie właściwości wartości null, ustaw właściwość IgnoreNullValues na true, jak pokazano w następującym przykładzie:To exclude all null value properties, set the IgnoreNullValues property to true, as shown in the following example:

var options = new JsonSerializerOptions
{
    IgnoreNullValues = true,
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);

Oto przykład obiektu do serializacji i danych wyjściowych JSON:Here's an example object to serialize and JSON output:

WłaściwośćProperty WartośćValue
DataDate 8/1/2019 12:00:00 AM – 07:008/1/2019 12:00:00 AM -07:00
TemperatureCelsiusTemperatureCelsius 2525
PodsumowanieSummary {1>null<1}null
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25
}

To ustawienie dotyczy serializacji i deserializacji.This setting applies to serialization and deserialization. Aby uzyskać informacje o jego wpływie na deserializacji, zobacz Ignore null podczas deserializacji.For information about its effect on deserialization, see Ignore null when deserializing.

Dostosuj kodowanie znakówCustomize character encoding

Domyślnie serializator wyprowadza wszystkie znaki nienależące do zestawu znaków ASCII.By default, the serializer escapes all non-ASCII characters. Oznacza to, że zastępuje je \uxxxx gdzie xxxx jest kodem Unicode znaku.That is, it replaces them with \uxxxx where xxxx is the Unicode code of the character. Na przykład, jeśli właściwość Summary jest ustawiona na wartość cyrylicy жарко, obiekt WeatherForecast zostanie Zserializowany, jak pokazano w tym przykładzie:For example, if the Summary property is set to Cyrillic жарко, the WeatherForecast object is serialized as shown in this example:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "\u0436\u0430\u0440\u043A\u043E"
}

Serializowanie zestawów znaków językaSerialize language character sets

Aby serializować zestawy znaków z co najmniej jednego języka bez ucieczki, określ zakresy Unicode podczas tworzenia wystąpienia System.Text.Encodings.Web.JavaScriptEncoder, jak pokazano w następującym przykładzie:To serialize the character set(s) of one or more languages without escaping, specify Unicode range(s) when creating an instance of System.Text.Encodings.Web.JavaScriptEncoder, as shown in the following example:

using System;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
options = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.Cyrillic),
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);

Ten kod nie ma ucieczki znaków cyrylicy lub greckich.This code doesn't escape Cyrillic or Greek characters. Jeśli właściwość Summary jest ustawiona na wartość cyrylicy жарко, obiekt WeatherForecast zostanie Zserializowany, jak pokazano w tym przykładzie:If the Summary property is set to Cyrillic жарко, the WeatherForecast object is serialized as shown in this example:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "жарко"
}

Aby serializować wszystkie zestawy językowe bez ucieczki, użyj UnicodeRanges.All.To serialize all language sets without escaping, use UnicodeRanges.All.

Serializacja określonych znakówSerialize specific characters

Alternatywą jest określenie pojedynczych znaków, które mają być dozwolone, bez konieczności ucieczki.An alternative is to specify individual characters that you want to allow through without being escaped. Poniższy przykład serializacji tylko dwa pierwsze znaki жарко:The following example serializes only the first two characters of жарко:

using System;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
var encoderSettings = new TextEncoderSettings();
encoderSettings.AllowCharacters('\u0436', '\u0430');
encoderSettings.AllowRange(UnicodeRanges.BasicLatin);
options = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.Create(encoderSettings),
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);

Oto przykład kodu JSON utworzonego przez poprzedni kod:Here's an example of JSON produced by the preceding code:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "жа\u0440\u043A\u043E"
}

Serializować wszystkie znakiSerialize all characters

Aby zminimalizować liczbę ucieczki, można użyć JavaScriptEncoder.UnsafeRelaxedJsonEscaping, jak pokazano w następującym przykładzie:To minimize escaping you can use JavaScriptEncoder.UnsafeRelaxedJsonEscaping, as shown in the following example:

using System;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
options = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);

Przestroga

W porównaniu z domyślnym koderem, koder UnsafeRelaxedJsonEscaping jest bardziej ograniczając, aby umożliwić Przechodzenie znaków przez niezmieniony:Compared to the default encoder, the UnsafeRelaxedJsonEscaping encoder is more permissive about allowing characters to pass through unescaped:

  • Nie wpływa to na znaki w języku HTML, takie jak <, >, &i '.It doesn't escape HTML-sensitive characters such as <, >, &, and '.
  • Nie oferuje żadnej dodatkowej ochrony przed atakami na ataki typu XSS lub ujawnienie informacji, takich jak te, które mogą wynikać z klienta i serwera bez zgody na zestaw znaków.It doesn't offer any additional defense-in-depth protections against XSS or information disclosure attacks, such as those which might result from the client and server disagreeing on the charset.

Używaj niebezpiecznego kodera tylko wtedy, gdy wiadomo, że klient będzie interpretować otrzymany ładunek jako zakodowany w formacie JSON UTF-8.Use the unsafe encoder only when it's known that the client will be interpreting the resulting payload as UTF-8 encoded JSON. Można na przykład użyć go, jeśli serwer wysyła nagłówek odpowiedzi Content-Type: application/json; charset=utf-8.For example, you can use it if the server is sending the response header Content-Type: application/json; charset=utf-8. Nigdy nie Zezwalaj na emitowanie nieprzetworzonych danych wyjściowych UnsafeRelaxedJsonEscaping do strony HTML lub <script> elementu.Never allow the raw UnsafeRelaxedJsonEscaping output to be emitted into an HTML page or a <script> element.

Serializowanie właściwości klas pochodnychSerialize properties of derived classes

Serializacja hierarchii typów polimorficznych nie jest obsługiwana.Serialization of a polymorphic type hierarchy is not supported. Na przykład, jeśli właściwość jest zdefiniowana jako interfejs lub Klasa abstrakcyjna, tylko właściwości zdefiniowane w interfejsie lub klasie abstrakcyjnej są serializowane, nawet jeśli typ środowiska uruchomieniowego ma dodatkowe właściwości.For example, if a property is defined as an interface or an abstract class, only the properties defined on the interface or abstract class are serialized, even if the runtime type has additional properties. Wyjątki dotyczące tego zachowania zostały omówione w tej sekcji.The exceptions to this behavior are explained in this section.

Załóżmy na przykład, że masz klasę WeatherForecast i klasę pochodną WeatherForecastDerived:For example, suppose you have a WeatherForecast class and a derived class WeatherForecastDerived:

public class WeatherForecast
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
}
public class WeatherForecastDerived : WeatherForecast
{
    public int WindSpeed { get; set; }
}

I Załóżmy, że argument typu metody Serialize w czasie kompilacji jest WeatherForecast:And suppose the type argument of the Serialize method at compile time is WeatherForecast:

var options = new JsonSerializerOptions
{
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize<WeatherForecast>(weatherForecast, options);

W tym scenariuszu Właściwość WindSpeed nie jest serializowana, nawet jeśli obiekt weatherForecast jest w rzeczywistości obiektem WeatherForecastDerived.In this scenario, the WindSpeed property is not serialized even if the weatherForecast object is actually a WeatherForecastDerived object. Tylko właściwości klasy bazowej są serializowane:Only the base class properties are serialized:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot"
}

Takie zachowanie ma na celu zapobieganie przypadkowemu narażeniu danych w pochodnym typie tworzonym przez środowisko uruchomieniowe.This behavior is intended to help prevent accidental exposure of data in a derived runtime-created type.

Aby serializować właściwości typu pochodnego w poprzednim przykładzie, należy użyć jednej z następujących metod:To serialize the properties of the derived type in the preceding example, use one of the following approaches:

  • Wywołaj Przeciążenie Serialize, które pozwala określić typ w czasie wykonywania:Call an overload of Serialize that lets you specify the type at runtime:

    options = new JsonSerializerOptions
    {
        WriteIndented = true
    };
    jsonString = JsonSerializer.Serialize(weatherForecast, weatherForecast.GetType(), options);
    
  • Zadeklaruj obiekt do serializacji jako object.Declare the object to be serialized as object.

    options = new JsonSerializerOptions
    {
        WriteIndented = true
    };
    jsonString = JsonSerializer.Serialize<object>(weatherForecast, options);
    

W poprzednim przykładowym scenariuszu oba podejścia powodują, że właściwość WindSpeed ma zostać uwzględniona w danych wyjściowych JSON:In the preceding example scenario, both approaches cause the WindSpeed property to be included in the JSON output:

{
  "WindSpeed": 35,
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot"
}

Ważne

Te podejścia zapewniają serializację polimorficzne tylko dla obiektu głównego, który ma być serializowany, a nie dla właściwości tego obiektu głównego.These approaches provide polymorphic serialization only for the root object to be serialized, not for properties of that root object.

Można uzyskać serializację polimorficzny dla obiektów niższego poziomu, jeśli zdefiniujesz je jako typ object.You can get polymorphic serialization for lower-level objects if you define them as type object. Załóżmy na przykład, że Klasa WeatherForecast ma właściwość o nazwie PreviousForecast, która może być zdefiniowana jako typ WeatherForecast lub object:For example, suppose your WeatherForecast class has a property named PreviousForecast that can be defined as type WeatherForecast or object:

public class WeatherForecastWithPrevious
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
    public WeatherForecast PreviousForecast { get; set; }
}
public class WeatherForecastWithPreviousAsObject
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
    public object PreviousForecast { get; set; }
}

Jeśli właściwość PreviousForecast zawiera wystąpienie WeatherForecastDerived:If the PreviousForecast property contains an instance of WeatherForecastDerived:

  • Dane wyjściowe JSON serializacji WeatherForecastWithPrevious nie obejmują WindSpeed.The JSON output from serializing WeatherForecastWithPrevious doesn't include WindSpeed.
  • Dane wyjściowe JSON serializacji WeatherForecastWithPreviousAsObject zawierają WindSpeed.The JSON output from serializing WeatherForecastWithPreviousAsObject includes WindSpeed.

Aby serializować WeatherForecastWithPreviousAsObject, nie jest konieczne wywołanie Serialize<object> lub GetType, ponieważ obiekt główny nie jest tym, który może znajdować się w typie pochodnym.To serialize WeatherForecastWithPreviousAsObject, it isn't necessary to call Serialize<object> or GetType because the root object isn't the one that may be of a derived type. Poniższy przykład kodu nie wywołuje Serialize<object> ani GetType:The following code example doesn't call Serialize<object> or GetType:

options = new JsonSerializerOptions
{
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecastWithPreviousAsObject, options);

Powyższy kod poprawnie serializować WeatherForecastWithPreviousAsObject:The preceding code correctly serializes WeatherForecastWithPreviousAsObject:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
  "PreviousForecast": {
    "WindSpeed": 35,
    "Date": "2019-08-01T00:00:00-07:00",
    "TemperatureCelsius": 25,
    "Summary": "Hot"
  }
}

Takie samo podejście do definiowania właściwości jako object współpracuje z interfejsami.The same approach of defining properties as object works with interfaces. Załóżmy, że masz następujący interfejs i implementacja, i chcesz serializować klasę o właściwościach zawierających wystąpienia implementacji:Suppose you have the following interface and implementation, and you want to serialize a class with properties that contain implementation instances:

using System;

namespace SystemTextJsonSamples
{
    public interface IForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string Summary { get; set; }
    }

    public class Forecast : IForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string Summary { get; set; }
        public int WindSpeed { get; set; }
    }

    public class Forecasts
    {
        public IForecast Monday { get; set; }
        public object Tuesday { get; set; }
    }
}

Podczas serializacji wystąpienia Forecaststylko Tuesday pokazuje Właściwość WindSpeed, ponieważ Tuesday jest zdefiniowana jako object:When you serialize an instance of Forecasts, only Tuesday shows the WindSpeed property, because Tuesday is defined as object:

var forecasts = new Forecasts
{
    Monday = new Forecast
    {
        Date = DateTime.Parse("2020-01-06"),
        TemperatureCelsius = 10,
        Summary = "Cool",
        WindSpeed = 8
    },
    Tuesday = new Forecast
    {
        Date = DateTime.Parse("2020-01-07"),
        TemperatureCelsius = 11,
        Summary = "Rainy",
        WindSpeed = 10
    }
};

options = new JsonSerializerOptions
{
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(forecasts, options);

Poniższy przykład pokazuje kod JSON, który wynika z poprzedniego kodu:The following example shows the JSON that results from the preceding code:

{
  "Monday": {
    "Date": "2020-01-06T00:00:00-08:00",
    "TemperatureCelsius": 10,
    "Summary": "Cool"
  },
  "Tuesday": {
    "Date": "2020-01-07T00:00:00-08:00",
    "TemperatureCelsius": 11,
    "Summary": "Rainy",
    "WindSpeed": 10
  }
}

Aby uzyskać więcej informacji na temat serializacjipolimorficznej i informacje o deserializacji, zobacz jak przeprowadzić migrację z Newtonsoft.Json do System.Text.Json.For more information about polymorphic serialization, and for information about deserialization, see How to migrate from Newtonsoft.Json to System.Text.Json.

Zezwalaj na komentarze i końcowe przecinkiAllow comments and trailing commas

Domyślnie Komentarze i końcowe przecinki są niedozwolone w notacji JSON.By default, comments and trailing commas are not allowed in JSON. Aby zezwolić na komentarze w formacie JSON, ustaw właściwość JsonSerializerOptions.ReadCommentHandling na JsonCommentHandling.Skip.To allow comments in the JSON, set the JsonSerializerOptions.ReadCommentHandling property to JsonCommentHandling.Skip. I aby zezwolić na końcowe przecinki, ustaw właściwość JsonSerializerOptions.AllowTrailingCommas na true.And to allow trailing commas, set the JsonSerializerOptions.AllowTrailingCommas property to true. Poniższy przykład pokazuje, jak:The following example shows how to allow both:

var options = new JsonSerializerOptions
{
    ReadCommentHandling = JsonCommentHandling.Skip,
    AllowTrailingCommas = true,
};
var weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString, options);

Oto przykładowy kod JSON z komentarzami i końcowym przecinkiem:Here's example JSON with comments and a trailing comma:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25, // Fahrenheit 77
  "Summary": "Hot", /* Zharko */
}

Dopasowanie właściwości bez uwzględniania wielkości literCase-insensitive property matching

Domyślnie deserializacja wyszukuje dopasowania nazw właściwości z uwzględnieniem wielkości liter między formatem JSON a właściwościami obiektu docelowego.By default, deserialization looks for case-sensitive property name matches between JSON and the target object properties. Aby zmienić to zachowanie, ustaw JsonSerializerOptions.PropertyNameCaseInsensitive na true:To change that behavior, set JsonSerializerOptions.PropertyNameCaseInsensitive to true:

var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true,
};
var weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString, options);

Oto przykład JSON z nazwami właściwości przypadku notacji CamelCase.Here's example JSON with camel case property names. Można ją zdeserializować do następującego typu, który ma nazwy właściwości przypadku języka Pascal.It can be deserialized into the following type that has Pascal case property names.

{
  "date": "2019-08-01T00:00:00-07:00",
  "temperatureCelsius": 25,
  "summary": "Hot",
}
public class WeatherForecast
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
}

Obsługa przepełnienia kodu JSONHandle overflow JSON

Podczas deserializacji można odbierać dane w formacie JSON, które nie są reprezentowane przez właściwości typu docelowego.While deserializing, you might receive data in the JSON that is not represented by properties of the target type. Załóżmy na przykład, że typ docelowy to:For example, suppose your target type is this:

public class WeatherForecast
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
}

I kod JSON do deserializacji jest następujący:And the JSON to be deserialized is this:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "temperatureCelsius": 25,
  "Summary": "Hot",
  "DatesAvailable": [
    "2019-08-01T00:00:00-07:00",
    "2019-08-02T00:00:00-07:00"
  ],
  "SummaryWords": [
    "Cool",
    "Windy",
    "Humid"
  ]
}

W przypadku deserializacji kodu JSON pokazanego w pokazanym typie właściwości DatesAvailable i SummaryWords mają wartość Nowhere i są tracone.If you deserialize the JSON shown into the type shown, the DatesAvailable and SummaryWords properties have nowhere to go and are lost. Aby przechwycić dodatkowe dane, takie jak te właściwości, zastosuj atrybut JsonExtensionData do właściwości typu Dictionary<string,object> lub Dictionary<string,JsonElement>:To capture extra data such as these properties, apply the JsonExtensionData attribute to a property of type Dictionary<string,object> or Dictionary<string,JsonElement>:

public class WeatherForecastWithExtensionData
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
    [JsonExtensionData]
    public Dictionary<string, object> ExtensionData { get; set; }
}

Podczas deserializacji kodu JSON pokazanego wcześniej w tym typie przykładowym dodatkowe dane staną się parami klucz-wartość właściwości ExtensionData:When you deserialize the JSON shown earlier into this sample type, the extra data becomes key-value pairs of the ExtensionData property:

WłaściwośćProperty WartośćValue UwagiNotes
DataDate 8/1/2019 12:00:00 AM – 07:008/1/2019 12:00:00 AM -07:00
TemperatureCelsiusTemperatureCelsius 00 Niezgodność z wielkością liter (temperatureCelsius w formacie JSON), więc właściwość nie jest ustawiona.Case-sensitive mismatch (temperatureCelsius in the JSON), so the property isn't set.
PodsumowanieSummary GorącaHot
ExtensionData —ExtensionData temperatureCelsius: 25temperatureCelsius: 25 Ponieważ przypadek nie jest zgodny, ta właściwość JSON jest dodatkową i jest parą klucz-wartość w słowniku.Since the case didn't match, this JSON property is an extra and becomes a key-value pair in the dictionary.
DatesAvailable:DatesAvailable:
8/1/2019 12:00:00 AM – 07:008/1/2019 12:00:00 AM -07:00
8/2/2019 12:00:00 AM – 07:008/2/2019 12:00:00 AM -07:00
Dodatkowa Właściwość JSON zmieni się na parę klucz-wartość, z tablicą jako obiektem wartości.Extra property from the JSON becomes a key-value pair, with an array as the value object.
SummaryWords:SummaryWords:
ChłodnaCool
WiatrWindy
HumidHumid
Dodatkowa Właściwość JSON zmieni się na parę klucz-wartość, z tablicą jako obiektem wartości.Extra property from the JSON becomes a key-value pair, with an array as the value object.

Gdy obiekt docelowy jest serializowany, pary wartości klucza danych rozszerzenia stają się właściwościami JSON tak samo jak w przychodzących danych JSON:When the target object is serialized, the extension data key value pairs become JSON properties just as they were in the incoming JSON:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 0,
  "Summary": "Hot",
  "temperatureCelsius": 25,
  "DatesAvailable": [
    "2019-08-01T00:00:00-07:00",
    "2019-08-02T00:00:00-07:00"
  ],
  "SummaryWords": [
    "Cool",
    "Windy",
    "Humid"
  ]
}

Zauważ, że nazwa właściwości ExtensionData nie jest wyświetlana w formacie JSON.Notice that the ExtensionData property name doesn't appear in the JSON. Takie zachowanie umożliwia wykonywanie operacji okrężnych przez kod JSON bez utraty jakichkolwiek dodatkowych danych, które w przeciwnym razie nie zostały odszeregowane.This behavior lets the JSON make a round trip without losing any extra data that otherwise wouldn't be deserialized.

Ignoruj wartość null podczas deserializacjiIgnore null when deserializing

Domyślnie, jeśli właściwość w formacie JSON ma wartość null, odpowiadająca jej właściwość w obiekcie docelowym ma wartość null.By default, if a property in JSON is null, the corresponding property in the target object is set to null. W niektórych scenariuszach właściwość target może mieć wartość domyślną i nie ma potrzeby przesłonięcia wartości domyślnej.In some scenarios, the target property might have a default value, and you don't want a null value to override the default.

Załóżmy na przykład, że następujący kod reprezentuje obiekt docelowy:For example, suppose the following code represents your target object:

public class WeatherForecastWithDefault
{
    public WeatherForecastWithDefault()
    {
        Date = DateTimeOffset.Parse("2001-01-01");
        Summary = "No summary";
    }
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
}

Załóżmy, że następujący kod JSON jest deserializowany:And suppose the following JSON is deserialized:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": null
}

Po deserializacji właściwość Summary obiektu WeatherForecastWithDefault ma wartość null.After deserialization, the Summary property of the WeatherForecastWithDefault object is null.

Aby zmienić to zachowanie, ustaw JsonSerializerOptions.IgnoreNullValues na true, jak pokazano w następującym przykładzie:To change this behavior, set JsonSerializerOptions.IgnoreNullValues to true, as shown in the following example:

var options = new JsonSerializerOptions
{
    IgnoreNullValues = true
};
weatherForecast = JsonSerializer.Deserialize<WeatherForecastWithDefault>(jsonString, options);

W przypadku tej opcji Właściwość Summary obiektu WeatherForecastWithDefault jest wartością domyślną "Brak podsumowania" po deserializacji.With this option, the Summary property of the WeatherForecastWithDefault object is the default value "No summary" after deserialization.

Wartości null w formacie JSON są ignorowane tylko wtedy, gdy są prawidłowe.Null values in the JSON are ignored only if they are valid. Wartości null dla typów wartości, które nie dopuszczają wartości null, powodują wyjątki.Null values for non-nullable value types cause exceptions.

Utf8JsonReader, Utf8JsonWriter i JsonDocumentUtf8JsonReader, Utf8JsonWriter, and JsonDocument

System.Text.Json.Utf8JsonReader jest wysoce wydajnym, niskim alokacją, czytnikiem tylko do przodu dla tekstu JSON zakodowanego w formacie UTF-8, Odczytaj ReadOnlySpan<byte> lub ReadOnlySequence<byte>.System.Text.Json.Utf8JsonReader is a high-performance, low allocation, forward-only reader for UTF-8 encoded JSON text, read from a ReadOnlySpan<byte> or ReadOnlySequence<byte>. Utf8JsonReader jest typem niskiego poziomu, który może służyć do tworzenia niestandardowych analizatorów i deserializacji.The Utf8JsonReader is a low-level type that can be used to build custom parsers and deserializers. Metoda JsonSerializer.Deserialize używa Utf8JsonReader w obszarze okładek.The JsonSerializer.Deserialize method uses Utf8JsonReader under the covers.

System.Text.Json.Utf8JsonWriter to wysoce wydajny sposób pisania zakodowanego tekstu JSON w formacie UTF-8 ze wspólnych typów platformy .NET, takich jak String, Int32i DateTime.System.Text.Json.Utf8JsonWriter is a high-performance way to write UTF-8 encoded JSON text from common .NET types like String, Int32, and DateTime. Składnik zapisywania jest typu niskiego poziomu, który może służyć do tworzenia serializatorów niestandardowych.The writer is a low-level type that can be used to build custom serializers. Metoda JsonSerializer.Serialize używa Utf8JsonWriter w obszarze okładek.The JsonSerializer.Serialize method uses Utf8JsonWriter under the covers.

System.Text.Json.JsonDocument zapewnia możliwość tworzenia Document Object Model tylko do odczytu (DOM) przy użyciu Utf8JsonReader.System.Text.Json.JsonDocument provides the ability to build a read-only Document Object Model (DOM) by using Utf8JsonReader. DOM zapewnia losowy dostęp do danych w ładunku JSON.The DOM provides random access to data in a JSON payload. Do elementów JSON, które tworzą ładunek, można uzyskać dostęp za pośrednictwem typu JsonElement.The JSON elements that compose the payload can be accessed via the JsonElement type. Typ JsonElement zapewnia moduł wyliczający tablic i obiektów oraz interfejsy API służące do konwertowania tekstu JSON na popularne typy .NET.The JsonElement type provides array and object enumerators along with APIs to convert JSON text to common .NET types. JsonDocument uwidacznia Właściwość RootElement.JsonDocument exposes a RootElement property.

W poniższych sekcjach pokazano, jak używać tych narzędzi do odczytywania i pisania danych JSON.The following sections show how to use these tools for reading and writing JSON.

Korzystanie z JsonDocument do uzyskiwania dostępu do danychUse JsonDocument for access to data

Poniższy przykład pokazuje, jak używać klasy JsonDocument do losowego dostępu do danych w ciągu JSON:The following example shows how to use the JsonDocument class for random access to data in a JSON string:

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}");

Powyższy kod ma następujące działanie:The preceding code:

  • Przyjęto, że kod JSON do analizy znajduje się w ciągu o nazwie jsonString.Assumes the JSON to analyze is in a string named jsonString.

  • Oblicza średnią ocenę dla obiektów w tablicy Students, która ma właściwość Grade.Calculates an average grade for objects in a Students array that have a Grade property.

  • Przypisuje domyślną ocenę 70 dla studentów, którzy nie posiadają klasy.Assigns a default grade of 70 for students who don't have a grade.

  • Zlicza uczniów przez zwiększenie zmiennej count przy każdej iteracji.Counts students by incrementing a count variable with each iteration. Alternatywą jest wywołanie GetArrayLength, jak pokazano w następującym przykładzie:An alternative is to call GetArrayLength, as shown in the following example:

    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}");
    

Oto przykład pliku JSON, który jest przetwarzany przez ten kod:Here's an example of the JSON that this code processes:

{
  "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
}

Użyj JsonDocument, aby zapisać kod JSONUse JsonDocument to write JSON

Poniższy przykład pokazuje, jak napisać kod JSON z JsonDocument:The following example shows how to write JSON from a 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();

Powyższy kod ma następujące działanie:The preceding code:

  • Odczytuje plik JSON, ładuje dane do JsonDocumenti zapisuje sformatowany plik JSON w formacie.Reads a JSON file, loads the data into a JsonDocument, and writes formatted (pretty-printed) JSON to a file.
  • Używa JsonDocumentOptions, aby określić, że komentarze w wejściowym formacie JSON są dozwolone, ale ignorowane.Uses JsonDocumentOptions to specify that comments in the input JSON are allowed but ignored.
  • Po zakończeniu wywołuje Flush w składniku zapisywania.When finished, calls Flush on the writer. Alternatywą jest umożliwienie składnika zapisywania AutoFlush, gdy zostanie on usunięty.An alternative is to let the writer autoflush when it's disposed.

Oto przykład danych wejściowych JSON do przetworzenia przez przykładowy kod:Here's an example of JSON input to be processed by the example code:

{"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}

Wynikiem są następujące niedrukowane dane wyjściowe JSON:The result is the following pretty-printed JSON output:

{
  "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
}

Użyj Utf8JsonWriterUse Utf8JsonWriter

Poniższy przykład pokazuje, jak używać klasy Utf8JsonWriter:The following example shows how to use the Utf8JsonWriter class:

var options = new JsonWriterOptions
{
    Indented = true
};

using (var stream = new MemoryStream())
{
    using (var writer = new Utf8JsonWriter(stream, options))
    {
        writer.WriteStartObject();
        writer.WriteString("date", DateTimeOffset.UtcNow);
        writer.WriteNumber("temp", 42);
        writer.WriteEndObject();
    }

    string json = Encoding.UTF8.GetString(stream.ToArray());
    Console.WriteLine(json);
}

Użyj Utf8JsonReaderUse Utf8JsonReader

Poniższy przykład pokazuje, jak używać klasy Utf8JsonReader:The following example shows how to use the Utf8JsonReader class:

var options = new JsonReaderOptions
{
    AllowTrailingCommas = true,
    CommentHandling = JsonCommentHandling.Skip
};
Utf8JsonReader reader = new Utf8JsonReader(jsonUtf8Bytes, options);

while (reader.Read())
{
    Console.Write(reader.TokenType);

    switch (reader.TokenType)
    {
        case JsonTokenType.PropertyName:
        case JsonTokenType.String:
            {
                string text = reader.GetString();
                Console.Write(" ");
                Console.Write(text);
                break;
            }

        case JsonTokenType.Number:
            {
                int intValue = reader.GetInt32();
                Console.Write(" ");
                Console.Write(intValue);
                break;
            }

            // Other token types elided for brevity
    }
    Console.WriteLine();
}

Poprzedni kod założono, że zmienna jsonUtf8 jest tablicą bajtów, która zawiera prawidłowy kod JSON zakodowany jako UTF-8.The preceding code assumes that the jsonUtf8 variable is a byte array that contains valid JSON, encoded as UTF-8.

Filtrowanie danych za pomocą Utf8JsonReaderFilter data using Utf8JsonReader

Poniższy przykład pokazuje, jak odczytywać plik synchronicznie i wyszukiwać wartość:The following example shows how to read a file synchronously and search for a value:

using System;
using System.IO;
using System.Text;
using System.Text.Json;

namespace SystemTextJsonSamples
{
    public class Utf8ReaderFromFile
    {
        private static readonly byte[] s_nameUtf8 = Encoding.UTF8.GetBytes("name");
        private static ReadOnlySpan<byte> Utf8Bom => new byte[] { 0xEF, 0xBB, 0xBF };
        public static void Run()
        {
            // ReadAllBytes if the file encoding is UTF-8:
            string fileName = "UniversitiesUtf8.json";
            ReadOnlySpan<byte> jsonReadOnlySpan = File.ReadAllBytes(fileName);

            // Read past the UTF-8 BOM bytes if a BOM exists.
            if (jsonReadOnlySpan.StartsWith(Utf8Bom))
            {
                jsonReadOnlySpan = jsonReadOnlySpan.Slice(Utf8Bom.Length);
            }

            // Or read as UTF-16 and transcode to UTF-8 to convert to a ReadOnlySpan<byte>
            //string fileName = "Universities.json";
            //string jsonString = File.ReadAllText(fileName);
            //ReadOnlySpan<byte> jsonReadOnlySpan = Encoding.UTF8.GetBytes(jsonString);


            int count = 0;
            int total = 0;

            var reader = new Utf8JsonReader(jsonReadOnlySpan);

            while (reader.Read())
            {
                JsonTokenType tokenType = reader.TokenType;

                switch (tokenType)
                {
                    case JsonTokenType.StartObject:
                        total++;
                        break;
                    case JsonTokenType.PropertyName:
                        if (reader.ValueTextEquals(s_nameUtf8))
                        {
                            // Assume valid JSON, known schema
                            reader.Read();
                            if (reader.GetString().EndsWith("University"))
                            {
                                count++;
                            }
                        }
                        break;
                }
            }
            Console.WriteLine($"{count} out of {total} have names that end with 'University'");
        }
    }
}

Powyższy kod ma następujące działanie:The preceding code:

  • Przyjęto, że kod JSON zawiera tablicę obiektów, a każdy obiekt może zawierać właściwość "name" typu String.Assumes the JSON contains an array of objects and each object may contain a "name" property of type string.

  • Zlicza obiekty i wartości właściwości "name", które kończą się znakiem "University".Counts objects and "name" property values that end with "University".

  • Przyjęto założenie, że plik jest zakodowany jako UTF-16 i transkoduje go do UTF-8.Assumes the file is encoded as UTF-16 and transcodes it into UTF-8. Plik zakodowany jako UTF-8 można odczytać bezpośrednio w ReadOnlySpan<byte>, używając następującego kodu:A file encoded as UTF-8 can be read directly into a ReadOnlySpan<byte>, by using the following code:

    ReadOnlySpan<byte> jsonReadOnlySpan = File.ReadAllBytes(fileName); 
    

    Jeśli plik zawiera znacznik kolejności bajtów UTF-8, usuń go przed przekazaniem bajtów do Utf8JsonReader, ponieważ czytnik oczekuje tekstu.If the file contains a UTF-8 byte order mark (BOM), remove it before passing the bytes to the Utf8JsonReader, since the reader expects text. W przeciwnym razie BOM jest traktowany jako nieprawidłowy kod JSON, a czytelnik zgłasza wyjątek.Otherwise, the BOM is considered invalid JSON, and the reader throws an exception.

Oto przykład JSON, który może odczytać poprzedzający kod.Here's a JSON sample that the preceding code can read. Otrzymany komunikat podsumowujący to "2 z 4 mają nazwy kończące się na" University ":The resulting summary message is "2 out of 4 have names that end with 'University'":

[
  {
    "web_pages": [ "https://contoso.edu/" ],
    "alpha_two_code": "US",
    "state-province": null,
    "country": "United States",
    "domains": [ "contoso.edu" ],
    "name": "Contoso Community College"
  },
  {
    "web_pages": [ "http://fabrikam.edu/" ],
    "alpha_two_code": "US",
    "state-province": null,
    "country": "United States",
    "domains": [ "fabrikam.edu" ],
    "name": "Fabrikam Community College"
  },
  {
    "web_pages": [ "http://www.contosouniversity.edu/" ],
    "alpha_two_code": "US",
    "state-province": null,
    "country": "United States",
    "domains": [ "contosouniversity.edu" ],
    "name": "Contoso University"
  },
  {
    "web_pages": [ "http://www.fabrikamuniversity.edu/" ],
    "alpha_two_code": "US",
    "state-province": null,
    "country": "United States",
    "domains": [ "fabrikamuniversity.edu" ],
    "name": "Fabrikam University"
  }
]

Dodatkowe zasobyAdditional resources