Como serializar e desserializar (empacotar e desempacotar) JSON no .NETHow to serialize and deserialize (marshal and unmarshal) JSON in .NET

Este artigo mostra como usar o System.Text.Json namespace para serializar e desserializar de e para o 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). Se você estiver portando um código existente do Newtonsoft.Json , consulte como migrar System.Text.Json para o .If you're porting existing code from Newtonsoft.Json, see How to migrate to System.Text.Json.

As direções e o código de exemplo usam a biblioteca diretamente, não por meio de uma estrutura como ASP.NET Core.The directions and sample code use the library directly, not through a framework such as ASP.NET Core.

A maior parte do código de exemplo de serialização define JsonSerializerOptions.WriteIndented como true "muito impresso" o JSON (com recuo e espaço em branco para legibilidade humana).Most of the serialization sample code sets JsonSerializerOptions.WriteIndented to true to "pretty-print" the JSON (with indentation and whitespace for human readability). Para uso em produção, você normalmente aceitaria o valor padrão de false para essa configuração.For production use, you would typically accept the default value of false for this setting.

Os exemplos de código referem-se à seguinte classe e variantes dela:The code examples refer to the following class and variants of it:

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

NamespacesNamespaces

O System.Text.Json namespace contém todos os pontos de entrada e os tipos principais.The System.Text.Json namespace contains all the entry points and the main types. O System.Text.Json.Serialization namespace contém atributos e APIs para cenários avançados e personalização específicas para serialização e desserialização.The System.Text.Json.Serialization namespace contains attributes and APIs for advanced scenarios and customization specific to serialization and deserialization. Os exemplos de código mostrados neste artigo exigem using diretivas para um ou ambos os namespaces: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;

System.Runtime.SerializationAtualmente, não há suporte para atributos do namespace no System.Text.Json .Attributes from the System.Runtime.Serialization namespace aren't currently supported in System.Text.Json.

Como gravar objetos .NET em JSON (Serialize)How to write .NET objects to JSON (serialize)

Para gravar JSON em uma cadeia de caracteres ou em um arquivo, chame o JsonSerializer.Serialize método.To write JSON to a string or to a file, call the JsonSerializer.Serialize method.

O exemplo a seguir cria JSON como uma cadeia de caracteres:The following example creates JSON as a string:

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

O exemplo a seguir usa código síncrono para criar um arquivo JSON:The following example uses synchronous code to create a JSON file:

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

O exemplo a seguir usa código assíncrono para criar um arquivo JSON:The following example uses asynchronous code to create a JSON file:

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

Os exemplos anteriores usam a inferência de tipos para o tipo que está sendo serializado.The preceding examples use type inference for the type being serialized. Uma sobrecarga de Serialize() usa um parâmetro de tipo genérico:An overload of Serialize() takes a generic type parameter:

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

Exemplo de serializaçãoSerialization example

Aqui está uma classe de exemplo que contém coleções e uma classe aninhada: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; }
}

A saída JSON da serialização de uma instância do tipo anterior é semelhante ao exemplo a seguir.The JSON output from serializing an instance of the preceding type looks like the following example. A saída JSON é reduzidos por padrão: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"]}

O exemplo a seguir mostra o mesmo JSON, formatado (ou seja, muito impresso com espaço em branco e recuo):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"
  ]
}

Serializar para UTF-8Serialize to UTF-8

Para serializar para UTF-8, chame o JsonSerializer.SerializeToUtf8Bytes método:To serialize to UTF-8, call the JsonSerializer.SerializeToUtf8Bytes method:

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

Uma Serialize sobrecarga que usa um Utf8JsonWriter também está disponível.A Serialize overload that takes a Utf8JsonWriter is also available.

A serialização para UTF-8 é de cerca de 5-10% mais rápida do que usar os métodos baseados em cadeia de caracteres.Serializing to UTF-8 is about 5-10% faster than using the string-based methods. A diferença é porque os bytes (como UTF-8) não precisam ser convertidos em cadeias de caracteres (UTF-16).The difference is because the bytes (as UTF-8) don't need to be converted to strings (UTF-16).

Comportamento de serializaçãoSerialization behavior

Os tipos com suporte incluem:Supported types include:

  • Primitivos .NET que mapeiam para primitivos JavaScript, como tipos numéricos, cadeias de caracteres e booliano..NET primitives that map to JavaScript primitives, such as numeric types, strings, and Boolean.
  • Pocos (objetos CLR antigos)definidos pelo usuário.User-defined Plain Old CLR Objects (POCOs).
  • Matrizes unidimensionais e denteadas ( ArrayName[][] ).One-dimensional and jagged arrays (ArrayName[][]).
  • Dictionary<string,TValue>onde TValue é object , JsonElement , ou um poco.Dictionary<string,TValue> where TValue is object, JsonElement, or a POCO.
  • Coleções dos namespaces a seguir.Collections from the following namespaces.

Você pode implementar conversores personalizados para lidar com tipos adicionais ou para fornecer funcionalidade que não é suportada pelos conversores internos.You can implement custom converters to handle additional types or to provide functionality that isn't supported by the built-in converters.

Como ler JSON em objetos .NET (desserializar)How to read JSON into .NET objects (deserialize)

Para desserializar de uma cadeia de caracteres ou de um arquivo, chame o JsonSerializer.Deserialize método.To deserialize from a string or a file, call the JsonSerializer.Deserialize method.

O exemplo a seguir lê JSON de uma cadeia de caracteres e cria uma instância da WeatherForecast classe mostrada anteriormente para o exemplo de serialização: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);

Para desserializar de um arquivo usando código síncrono, leia o arquivo em uma cadeia de caracteres, conforme mostrado no exemplo a seguir: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);

Para desserializar de um arquivo usando código assíncrono, chame o DeserializeAsync método: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);
}

Desserializar de UTF-8Deserialize from UTF-8

Para desserializar do UTF-8, chame uma JsonSerializer.Deserialize sobrecarga que usa um Utf8JsonReader ou um ReadOnlySpan<byte> , conforme mostrado nos exemplos a seguir.To deserialize from UTF-8, call a JsonSerializer.Deserialize overload that takes a Utf8JsonReader or a ReadOnlySpan<byte>, as shown in the following examples. Os exemplos pressupõem que o JSON esteja em uma matriz de bytes chamada 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);

Comportamento de desserializaçãoDeserialization behavior

Você pode implementar conversores personalizados para fornecer funcionalidade que não é suportada pelos conversores internos.You can implement custom converters to provide functionality that isn't supported by the built-in converters.

Serializar para JSON formatadoSerialize to formatted JSON

Para imprimir a saída JSON com muita impressão, defina JsonSerializerOptions.WriteIndented como true :To pretty-print the JSON output, set JsonSerializerOptions.WriteIndented to true:

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

Aqui está um tipo de exemplo a ser serializado e a saída JSON bem impressa: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"
}

Personalizar nomes e valores JSONCustomize JSON names and values

Por padrão, os nomes de propriedade e as chaves de dicionário são inalterados na saída JSON, incluindo maiúsculas e minúsculas.By default, property names and dictionary keys are unchanged in the JSON output, including case. Os valores de enumeração são representados como números.Enum values are represented as numbers. Esta seção explica como:This section explains how to:

Para outros cenários que exigem tratamento especial de valores e nomes de propriedade JSON, você pode implementar conversores personalizados.For other scenarios that require special handling of JSON property names and values, you can implement custom converters.

Personalizar nomes de propriedade individuaisCustomize individual property names

Para definir o nome de propriedades individuais, use o atributo [JsonPropertyName] .To set the name of individual properties, use the [JsonPropertyName] attribute.

Veja um exemplo de tipo para serializar e o JSON resultante: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
}

O nome da propriedade definido por este atributo:The property name set by this attribute:

  • Aplica-se em ambas as direções, para serialização e desserialização.Applies in both directions, for serialization and deserialization.
  • Tem precedência sobre as políticas de nomenclatura de propriedade.Takes precedence over property naming policies.

Usar o camel case para todos os nomes de propriedade JSONUse camel case for all JSON property names

Para usar o camel case para todos os nomes de propriedade JSON, defina como JsonSerializerOptions.PropertyNamingPolicy JsonNamingPolicy.CamelCase , conforme mostrado no exemplo a seguir: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);

Aqui está uma classe de exemplo para serializar e a saída 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
}

A política de nomenclatura de Propriedade do camel case:The camel case property naming policy:

  • Aplica-se à serialização e desserialização.Applies to serialization and deserialization.
  • É substituído por [JsonPropertyName] atributos.Is overridden by [JsonPropertyName] attributes. É por isso que o nome da propriedade JSON Wind no exemplo não é camel case.This is why the JSON property name Wind in the example is not camel case.

Usar uma política de nomenclatura de propriedade JSON personalizadaUse a custom JSON property naming policy

Para usar uma política de nomenclatura de propriedade JSON personalizada, crie uma classe derivada de JsonNamingPolicy e substitua o ConvertName método, conforme mostrado no exemplo a seguir: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();
    }
}

Em seguida, defina a JsonSerializerOptions.PropertyNamingPolicy propriedade como uma instância da sua classe de política de nomenclatura: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);

Aqui está uma classe de exemplo para serializar e a saída 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
}

A política de nomenclatura de propriedade JSON:The JSON property naming policy:

  • Aplica-se à serialização e desserialização.Applies to serialization and deserialization.
  • É substituído por [JsonPropertyName] atributos.Is overridden by [JsonPropertyName] attributes. É por isso que o nome da propriedade JSON Wind no exemplo não é maiúscula.This is why the JSON property name Wind in the example is not upper case.

Chaves de dicionário do camel caseCamel case dictionary keys

Se uma propriedade de um objeto a ser serializado for do tipo Dictionary<string,TValue> , as string chaves poderão ser convertidas em camel case.If a property of an object to be serialized is of type Dictionary<string,TValue>, the string keys can be converted to camel case. Para fazer isso, defina DictionaryKeyPolicy como JsonNamingPolicy.CamelCase , conforme mostrado no exemplo a seguir: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);

Serializar um objeto com um dicionário chamado TemperatureRanges que tem pares chave-valor "ColdMinTemp", 20 e "HotMinTemp", 40 resultaria em uma saída JSON como o exemplo a seguir: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
  }
}

A política de nomenclatura do camel case para chaves de dicionário se aplica somente à serialização.The camel case naming policy for dictionary keys applies to serialization only. Se você desserializar um dicionário, as chaves corresponderão ao arquivo JSON mesmo que você especifique JsonNamingPolicy.CamelCase para o DictionaryKeyPolicy .If you deserialize a dictionary, the keys will match the JSON file even if you specify JsonNamingPolicy.CamelCase for the DictionaryKeyPolicy.

Enumerações como cadeias de caracteresEnums as strings

Por padrão, as enumerações são serializadas como números.By default, enums are serialized as numbers. Para serializar nomes de enumeração como cadeias de caracteres, use o JsonStringEnumConverter .To serialize enum names as strings, use the JsonStringEnumConverter.

Por exemplo, suponha que você precise serializar a seguinte classe que tem uma enumeração: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
}

Se o resumo for Hot , por padrão, o JSON serializado terá o valor numérico 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
}

O código de exemplo a seguir serializa os nomes de enumeração em vez dos valores numéricos e converte os nomes em camel case: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);

O JSON resultante é semelhante ao exemplo a seguir:The resulting JSON looks like the following example:

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

Os nomes de cadeias de caracteres de enumeração também podem ser desserializados, conforme mostrado no exemplo a seguir: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);

Excluir propriedades da serializaçãoExclude properties from serialization

Por padrão, todas as propriedades públicas são serializadas.By default, all public properties are serialized. Se você não quiser que alguns deles apareçam na saída JSON, terá várias opções.If you don't want some of them to appear in the JSON output, you have several options. Esta seção explica como excluir:This section explains how to exclude:

Excluir propriedades individuaisExclude individual properties

Para ignorar as propriedades individuais, use o atributo [JsonIgnore] .To ignore individual properties, use the [JsonIgnore] attribute.

Aqui está um tipo de exemplo para serializar e a saída 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,
}

Excluir todas as propriedades somente leituraExclude all read-only properties

Uma propriedade será somente leitura se ela contiver um getter público, mas não um setter público.A property is read-only if it contains a public getter but not a public setter. Para excluir todas as propriedades somente leitura, defina como JsonSerializerOptions.IgnoreReadOnlyProperties true , conforme mostrado no exemplo a seguir: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);

Aqui está um tipo de exemplo para serializar e a saída 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",
}

Essa opção se aplica somente à serialização.This option applies only to serialization. Durante a desserialização, as propriedades somente leitura são ignoradas por padrão.During deserialization, read-only properties are ignored by default.

Excluir todas as propriedades de valor nuloExclude all null value properties

Para excluir todas as propriedades de valor nulo, defina a IgnoreNullValues propriedade como true , conforme mostrado no exemplo a seguir: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);

Aqui está um objeto de exemplo para serializar e a saída JSON:Here's an example object to serialize and JSON output:

PropriedadeProperty ValorValue
DataDate 8/1/2019 12:00:00 AM-07:008/1/2019 12:00:00 AM -07:00
TemperatureCelsiusTemperatureCelsius 2525
ResumoSummary nulonull
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25
}

Essa configuração se aplica à serialização e desserialização.This setting applies to serialization and deserialization. Para obter informações sobre o efeito na desserialização, consulte ignorar nulo ao desserializar.For information about its effect on deserialization, see Ignore null when deserializing.

Personalizar codificação de caracteresCustomize character encoding

Por padrão, o serializador escapa todos os caracteres não ASCII.By default, the serializer escapes all non-ASCII characters. Ou seja, ele substitui por \uxxxx onde xxxx está o código Unicode do caractere.That is, it replaces them with \uxxxx where xxxx is the Unicode code of the character. Por exemplo, se a Summary propriedade for definida como cirílico жарко, o WeatherForecast objeto será serializado, conforme mostrado neste exemplo: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"
}

Serializar conjuntos de caracteres de idiomaSerialize language character sets

Para serializar os conjuntos de caracteres de um ou mais idiomas sem saída, especifique os intervalos Unicode ao criar uma instância do System.Text.Encodings.Web.JavaScriptEncoder , conforme mostrado no exemplo a seguir: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);

Este código não sai de escape de caracteres cirílico ou grego.This code doesn't escape Cyrillic or Greek characters. Se a Summary propriedade for definida como cirílico жарко, o WeatherForecast objeto será serializado, conforme mostrado neste exemplo: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": "жарко"
}

Para serializar todos os conjuntos de idiomas sem saída, use UnicodeRanges.All .To serialize all language sets without escaping, use UnicodeRanges.All.

Serializar caracteres específicosSerialize specific characters

Uma alternativa é especificar os caracteres individuais que você deseja permitir sem ter escape.An alternative is to specify individual characters that you want to allow through without being escaped. O exemplo a seguir serializa apenas os dois primeiros caracteres de жарко: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);

Aqui está um exemplo de JSON produzido pelo código anterior: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"
}

Serializar todos os caracteresSerialize all characters

Para minimizar a saída, você pode usar JavaScriptEncoder.UnsafeRelaxedJsonEscaping , conforme mostrado no exemplo a seguir: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);

Cuidado

Em comparação com o codificador padrão, o UnsafeRelaxedJsonEscaping codificador é mais permissivo de permitir que os caracteres passem sem escape:Compared to the default encoder, the UnsafeRelaxedJsonEscaping encoder is more permissive about allowing characters to pass through unescaped:

  • Ele não sai de caracteres sensíveis a HTML, como < ,, > & e ' .It doesn't escape HTML-sensitive characters such as <, >, &, and '.
  • Ele não oferece nenhuma proteção adicional de defesa profunda contra ataques XSS ou de divulgação de informações, como aqueles que podem resultar do cliente e do servidor que estão descordando no conjunto de caracteres.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.

Use o codificador não seguro somente quando for conhecido que o cliente irá interpretar a carga resultante como JSON codificado em 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. Por exemplo, você pode usá-lo se o servidor estiver enviando o cabeçalho de resposta 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. Nunca permita que a UnsafeRelaxedJsonEscaping saída bruta seja emitida em uma página HTML ou em um <script> elemento.Never allow the raw UnsafeRelaxedJsonEscaping output to be emitted into an HTML page or a <script> element.

Serializar Propriedades de classes derivadasSerialize properties of derived classes

Não há suporte para a serialização de uma hierarquia de tipo polimórfico.Serialization of a polymorphic type hierarchy is not supported. Por exemplo, se uma propriedade for definida como uma interface ou uma classe abstrata, somente as propriedades definidas na interface ou na classe abstrata serão serializadas, mesmo que o tipo de tempo de execução tenha propriedades adicionais.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. As exceções a esse comportamento são explicadas nesta seção.The exceptions to this behavior are explained in this section.

Por exemplo, suponha que você tenha uma WeatherForecast classe e uma classe derivada 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; }
}

E suponha que o argumento de tipo do Serialize método em tempo de compilação seja 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);

Nesse cenário, a WindSpeed propriedade não é serializada, mesmo que o weatherForecast objeto seja, na verdade, um WeatherForecastDerived objeto.In this scenario, the WindSpeed property is not serialized even if the weatherForecast object is actually a WeatherForecastDerived object. Somente as propriedades da classe base são serializadas:Only the base class properties are serialized:

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

Esse comportamento destina-se a ajudar a evitar a exposição acidental de dados em um tipo criado de tempo de execução derivado.This behavior is intended to help prevent accidental exposure of data in a derived runtime-created type.

Para serializar as propriedades do tipo derivado no exemplo anterior, use uma das seguintes abordagens:To serialize the properties of the derived type in the preceding example, use one of the following approaches:

  • Chame uma sobrecarga de Serialize que permite especificar o tipo em tempo de execução:Call an overload of Serialize that lets you specify the type at run time:

    options = new JsonSerializerOptions
    {
        WriteIndented = true
    };
    jsonString = JsonSerializer.Serialize(weatherForecast, weatherForecast.GetType(), options);
    
  • Declare o objeto a ser serializado como object .Declare the object to be serialized as object.

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

No cenário de exemplo anterior, ambas as abordagens fazem com que a WindSpeed propriedade seja incluída na saída 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"
}

Importante

Essas abordagens fornecem serialização polimórfica somente para o objeto raiz a ser serializado, não para propriedades desse objeto raiz.These approaches provide polymorphic serialization only for the root object to be serialized, not for properties of that root object.

Você pode obter a serialização polimórfica para objetos de nível inferior se defini-los como tipo object .You can get polymorphic serialization for lower-level objects if you define them as type object. Por exemplo, suponha que sua WeatherForecast classe tenha uma propriedade chamada PreviousForecast que possa ser definida como tipo WeatherForecast ou 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; }
}

Se a PreviousForecast Propriedade contiver uma instância de WeatherForecastDerived :If the PreviousForecast property contains an instance of WeatherForecastDerived:

  • A saída JSON da serialização WeatherForecastWithPrevious não inclui WindSpeed .The JSON output from serializing WeatherForecastWithPrevious doesn't include WindSpeed.
  • A saída JSON da serialização WeatherForecastWithPreviousAsObject inclui WindSpeed .The JSON output from serializing WeatherForecastWithPreviousAsObject includes WindSpeed.

Para serializar WeatherForecastWithPreviousAsObject , não é necessário chamar Serialize<object> ou GetType porque o objeto raiz não é aquele que pode ser de um tipo derivado.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. O exemplo de código a seguir não chama Serialize<object> ou GetType :The following code example doesn't call Serialize<object> or GetType:

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

O código anterior serializa corretamente 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"
  }
}

A mesma abordagem de definir propriedades como object funciona com interfaces.The same approach of defining properties as object works with interfaces. Suponha que você tenha a seguinte interface e implementação e queira serializar uma classe com propriedades que contêm instâncias de implementação: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; }
    }
}

Quando você serializa uma instância do Forecasts , Tuesday o mostra apenas a WindSpeed propriedade, porque Tuesday é definido como 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);

O exemplo a seguir mostra o JSON que resulta do código anterior: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
  }
}

Para obter mais informações sobre a serializaçãopolimórfica e informações sobre a desserialização, consulte como migrar do Newtonsoft.Json para System.Text.Json o .For more information about polymorphic serialization, and for information about deserialization, see How to migrate from Newtonsoft.Json to System.Text.Json.

Permitir comentários e vírgulas à direitaAllow comments and trailing commas

Por padrão, comentários e vírgulas à direita não são permitidos em JSON.By default, comments and trailing commas are not allowed in JSON. Para permitir comentários no JSON, defina a JsonSerializerOptions.ReadCommentHandling propriedade como JsonCommentHandling.Skip .To allow comments in the JSON, set the JsonSerializerOptions.ReadCommentHandling property to JsonCommentHandling.Skip. E para permitir vírgulas à direita, defina a JsonSerializerOptions.AllowTrailingCommas propriedade como true .And to allow trailing commas, set the JsonSerializerOptions.AllowTrailingCommas property to true. O exemplo a seguir mostra como permitir:The following example shows how to allow both:

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

Aqui está um exemplo de JSON com comentários e uma vírgula à direita: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 */
}

Correspondência de propriedade que não diferencia maiúsculas de minúsculasCase-insensitive property matching

Por padrão, a desserialização procura as correspondências de nome de propriedade que diferenciam maiúsculas de minúsculas entre JSON e as propriedades do objeto de destino.By default, deserialization looks for case-sensitive property name matches between JSON and the target object properties. Para alterar esse comportamento, defina JsonSerializerOptions.PropertyNameCaseInsensitive como true :To change that behavior, set JsonSerializerOptions.PropertyNameCaseInsensitive to true:

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

Aqui está um exemplo de JSON com nomes de Propriedade do camel case.Here's example JSON with camel case property names. Ele pode ser desserializado no seguinte tipo que tem nomes de propriedade de caso de 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; }
}

Processar JSON de estouroHandle overflow JSON

Durante a desserialização, você pode receber dados no JSON que não são representados pelas propriedades do tipo de destino.While deserializing, you might receive data in the JSON that is not represented by properties of the target type. Por exemplo, suponha que o tipo de destino seja o seguinte: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; }
}

E o JSON a ser desserializado é o seguinte: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"
  ]
}

Se você desserializar o JSON mostrado no tipo mostrado, as DatesAvailable Propriedades e SummaryWords ficarão sem lugar e serão perdidas.If you deserialize the JSON shown into the type shown, the DatesAvailable and SummaryWords properties have nowhere to go and are lost. Para capturar dados adicionais, como essas propriedades, aplique o atributo JsonExtensionData a uma propriedade do tipo Dictionary<string,object> ou 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; }
}

Quando você desserializar o JSON mostrado anteriormente neste tipo de exemplo, os dados extras se tornarão pares de chave-valor da ExtensionData Propriedade:When you deserialize the JSON shown earlier into this sample type, the extra data becomes key-value pairs of the ExtensionData property:

PropriedadeProperty ValorValue ObservaçõesNotes
DataDate 8/1/2019 12:00:00 AM-07:008/1/2019 12:00:00 AM -07:00
TemperatureCelsiusTemperatureCelsius 00 Incompatibilidade de maiúsculas e minúsculas ( temperatureCelsius no JSON), portanto, a propriedade não está definida.Case-sensitive mismatch (temperatureCelsius in the JSON), so the property isn't set.
ResumoSummary DinâmicaHot
ExtensionDataExtensionData temperatureCelsius: 25temperatureCelsius: 25 Como o caso não corresponde, essa propriedade JSON é um extra e se torna um par chave-valor no dicionário.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
A propriedade extra do JSON torna-se um par chave-valor, com uma matriz como o objeto de valor.Extra property from the JSON becomes a key-value pair, with an array as the value object.
SummaryWords:SummaryWords:
EstáticaCool
VentoWindy
HumidHumid
A propriedade extra do JSON torna-se um par chave-valor, com uma matriz como o objeto de valor.Extra property from the JSON becomes a key-value pair, with an array as the value object.

Quando o objeto de destino é serializado, os pares de valor de chave de dados de extensão se tornam propriedades JSON, assim como no JSON de entrada: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"
  ]
}

Observe que o ExtensionData nome da propriedade não aparece no JSON.Notice that the ExtensionData property name doesn't appear in the JSON. Esse comportamento permite que o JSON faça uma viagem de ida e volta sem perder nenhum dado extra que, de outra forma, não seria desserializado.This behavior lets the JSON make a round trip without losing any extra data that otherwise wouldn't be deserialized.

Ignorar nulo ao desserializarIgnore null when deserializing

Por padrão, se uma propriedade em JSON for nula, a propriedade correspondente no objeto de destino será definida como NULL.By default, if a property in JSON is null, the corresponding property in the target object is set to null. Em alguns cenários, a propriedade de destino pode ter um valor padrão e você não quer um valor nulo para substituir o padrão.In some scenarios, the target property might have a default value, and you don't want a null value to override the default.

Por exemplo, suponha que o código a seguir represente o objeto de destino: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; }
}

E suponha que o JSON a seguir seja desserializado:And suppose the following JSON is deserialized:

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

Após a desserialização, a Summary Propriedade do WeatherForecastWithDefault objeto é nula.After deserialization, the Summary property of the WeatherForecastWithDefault object is null.

Para alterar esse comportamento, defina JsonSerializerOptions.IgnoreNullValues como true , conforme mostrado no exemplo a seguir: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);

Com essa opção, a Summary Propriedade do WeatherForecastWithDefault objeto é o valor padrão "sem Resumo" após a desserialização.With this option, the Summary property of the WeatherForecastWithDefault object is the default value "No summary" after deserialization.

Os valores nulos no JSON serão ignorados somente se forem válidos.Null values in the JSON are ignored only if they are valid. Valores nulos para tipos de valores não anuláveis causam exceções.Null values for non-nullable value types cause exceptions.

Utf8JsonReader, Utf8JsonWriter e JsonDocumentUtf8JsonReader, Utf8JsonWriter, and JsonDocument

System.Text.Json.Utf8JsonReaderé um leitor de alto desempenho, de baixa alocação e somente de encaminhamento para texto JSON codificado em UTF-8, lido de um ReadOnlySpan<byte> ou 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>. O Utf8JsonReader é um tipo de baixo nível que pode ser usado para criar analisadores e desserializadores personalizados.The Utf8JsonReader is a low-level type that can be used to build custom parsers and deserializers. O JsonSerializer.Deserialize método usa Utf8JsonReader nos bastidores.The JsonSerializer.Deserialize method uses Utf8JsonReader under the covers.

System.Text.Json.Utf8JsonWriteré uma maneira de alto desempenho para escrever texto JSON codificado em UTF-8 de tipos comuns do .NET como String , Int32 e 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. O gravador é um tipo de baixo nível que pode ser usado para criar serializadores personalizados.The writer is a low-level type that can be used to build custom serializers. O JsonSerializer.Serialize método usa Utf8JsonWriter nos bastidores.The JsonSerializer.Serialize method uses Utf8JsonWriter under the covers.

System.Text.Json.JsonDocumentfornece a capacidade de criar um Modelo de Objeto do Documento somente leitura (DOM) usando o Utf8JsonReader .System.Text.Json.JsonDocument provides the ability to build a read-only Document Object Model (DOM) by using Utf8JsonReader. O DOM fornece acesso aleatório aos dados em uma carga JSON.The DOM provides random access to data in a JSON payload. Os elementos JSON que compõem a carga podem ser acessados por meio do JsonElement tipo.The JSON elements that compose the payload can be accessed via the JsonElement type. O JsonElement tipo fornece enumeradores de matriz e de objeto juntamente com APIs para converter texto JSON em tipos .net comuns.The JsonElement type provides array and object enumerators along with APIs to convert JSON text to common .NET types. JsonDocumentexpõe uma RootElement propriedade.JsonDocument exposes a RootElement property.

As seções a seguir mostram como usar essas ferramentas para ler e gravar o JSON.The following sections show how to use these tools for reading and writing JSON.

Usar o JsonDocument para acessar dadosUse JsonDocument for access to data

O exemplo a seguir mostra como usar a JsonDocument classe para acesso aleatório a dados em uma cadeia de caracteres 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}");

O código anterior:The preceding code:

  • Assume que o JSON a ser analisado está em uma cadeia de caracteres chamada jsonString .Assumes the JSON to analyze is in a string named jsonString.

  • Calcula uma classificação média para objetos em uma Students matriz que tem uma Grade propriedade.Calculates an average grade for objects in a Students array that have a Grade property.

  • Atribui uma classificação padrão de 70 para alunos que não têm uma classificação.Assigns a default grade of 70 for students who don't have a grade.

  • Conta os alunos incrementando uma count variável com cada iteração.Counts students by incrementing a count variable with each iteration. Uma alternativa é chamar GetArrayLength , conforme mostrado no exemplo a seguir: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}");
    

Veja um exemplo do JSON que esse código processa: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
}

Usar JsonDocument para gravar JSONUse JsonDocument to write JSON

O exemplo a seguir mostra como gravar JSON de um 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();

O código anterior:The preceding code:

  • Lê um arquivo JSON, carrega os dados em um JsonDocument e grava JSON formatado (bem-impresso) em um arquivo.Reads a JSON file, loads the data into a JsonDocument, and writes formatted (pretty-printed) JSON to a file.
  • Usa JsonDocumentOptions para especificar que os comentários no JSON de entrada são permitidos, mas ignorados.Uses JsonDocumentOptions to specify that comments in the input JSON are allowed but ignored.
  • Quando terminar, chama Flush o gravador.When finished, calls Flush on the writer. Uma alternativa é deixar o gravador AutoFlush quando ele é Descartado.An alternative is to let the writer autoflush when it's disposed.

Aqui está um exemplo de entrada JSON a ser processada pelo código de exemplo: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}

O resultado é a seguinte saída JSON bem impressa: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
}

Usar Utf8JsonWriterUse Utf8JsonWriter

O exemplo a seguir mostra como usar a Utf8JsonWriter classe: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);
}

Usar Utf8JsonReaderUse Utf8JsonReader

O exemplo a seguir mostra como usar a Utf8JsonReader classe: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();
}

O código anterior pressupõe que a jsonUtf8 variável é uma matriz de bytes que contém um JSON válido, codificado como UTF-8.The preceding code assumes that the jsonUtf8 variable is a byte array that contains valid JSON, encoded as UTF-8.

Filtrar dados usando Utf8JsonReaderFilter data using Utf8JsonReader

O exemplo a seguir mostra como ler um arquivo de forma síncrona e procurar um valor: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'");
        }
    }
}

O código anterior:The preceding code:

  • Assume que o JSON contém uma matriz de objetos e cada objeto pode conter uma propriedade "Name" do tipo cadeia de caracteres.Assumes the JSON contains an array of objects and each object may contain a "name" property of type string.

  • Conta objetos e valores de propriedade "Name" que terminam com "University".Counts objects and "name" property values that end with "University".

  • Pressupõe que o arquivo é codificado como UTF-16 e o codifica em UTF-8.Assumes the file is encoded as UTF-16 and transcodes it into UTF-8. Um arquivo codificado como UTF-8 pode ser lido diretamente em um ReadOnlySpan<byte> , usando o seguinte código: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);
    

    Se o arquivo contiver uma marca de ordem de byte (BOM) UTF-8, remova-a antes de passar os bytes para o Utf8JsonReader , uma vez que o leitor espera o texto.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. Caso contrário, a BOM será considerada JSON inválido e o leitor lançará uma exceção.Otherwise, the BOM is considered invalid JSON, and the reader throws an exception.

Aqui está um exemplo de JSON que o código anterior pode ler.Here's a JSON sample that the preceding code can read. A mensagem de resumo resultante é "2 de 4 têm nomes que terminam com" 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"
  }
]

Ler de um fluxo usando Utf8JsonReaderRead from a stream using Utf8JsonReader

Ao ler um arquivo grande (um gigabyte ou mais, por exemplo), talvez você queira evitar ter que carregar todo o arquivo na memória de uma só vez.When reading a large file (a gigabyte or more in size, for example), you might want to avoid having to load the entire file into memory at once. Para esse cenário, você pode usar um FileStream .For this scenario, you can use a FileStream.

Ao usar o Utf8JsonReader para ler de um fluxo, as seguintes regras se aplicam:When using the Utf8JsonReader to read from a stream, the following rules apply:

  • O buffer que contém a carga JSON parcial deve ser pelo menos tão grande quanto o maior token JSON dentro dele, de modo que o leitor possa progredir em encaminhar.The buffer containing the partial JSON payload must be at least as big as the largest JSON token within it so that the reader can make forward progress.
  • O buffer deve ser pelo menos tão grande quanto a maior sequência de espaços em branco dentro do JSON.The buffer must be at least as big as the largest sequence of white space within the JSON.
  • O leitor não mantém o controle dos dados lidos até que ele leia completamente o próximo TokenType na carga JSON.The reader doesn't keep track of the data it has read until it completely reads the next TokenType in the JSON payload. Assim, quando houver bytes restantes no buffer, você precisa passá-los para o leitor novamente.So when there are bytes left over in the buffer, you have to pass them to the reader again. Você pode usar BytesConsumed para determinar quantos bytes serão deixados.You can use BytesConsumed to determine how many bytes are left over.

O código a seguir ilustra como ler de um fluxo.The following code illustrates how to read from a stream. O exemplo mostra um MemoryStream .The example shows a MemoryStream. O código semelhante funcionará com um FileStream , exceto quando o FileStream contiver uma bom UTF-8 no início.Similar code will work with a FileStream, except when the FileStream contains a UTF-8 BOM at the start. Nesse caso, você precisa remover esses três bytes do buffer antes de passar os bytes restantes para o Utf8JsonReader .In that case, you need to strip those three bytes from the buffer before passing the remaining bytes to the Utf8JsonReader. Caso contrário, o leitor lançaria uma exceção, uma vez que a BOM não é considerada uma parte válida do JSON.Otherwise the reader would throw an exception, since the BOM is not considered a valid part of the JSON.

O código de exemplo começa com um buffer de 4 KB e dobra o tamanho do buffer sempre que ele descobre que o tamanho não é grande o suficiente para se ajustar a um token JSON completo, que é necessário para que o leitor faça o progresso no conteúdo JSON.The sample code starts with a 4KB buffer and doubles the buffer size each time it finds that the size is not big enough to fit a complete JSON token, which is required for the reader to make forward progress on the JSON payload. O exemplo de JSON fornecido no trecho de código dispara um aumento de tamanho de buffer somente se você definir um tamanho de buffer inicial muito pequeno, por exemplo, 10 bytes.The JSON sample provided in the snippet triggers a buffer size increase only if you set a very small initial buffer size, for example, 10 bytes. Se você definir o tamanho do buffer inicial como 10, as Console.WriteLine instruções ilustrarão a causa e o efeito do tamanho do buffer aumentará.If you set the initial buffer size to 10, the Console.WriteLine statements illustrate the cause and effect of buffer size increases. No tamanho do buffer inicial de 4 KB, o JSON de exemplo inteiro é mostrado por cada um Console.WriteLine , e o tamanho do buffer nunca precisa ser aumentado.At the 4KB initial buffer size, the entire sample JSON is shown by each Console.WriteLine, and the buffer size never has to be increased.

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

namespace SystemTextJsonSamples
{
    public class Utf8ReaderPartialRead
    {
        public static void Run()
        {
            var jsonString = @"{
                ""Date"": ""2019-08-01T00:00:00-07:00"",
                ""Temperature"": 25,
                ""TemperatureRanges"": {
                    ""Cold"": { ""High"": 20, ""Low"": -10 },
                    ""Hot"": { ""High"": 60, ""Low"": 20 }
                },
                ""Summary"": ""Hot"",
            }";

            byte[] bytes = Encoding.UTF8.GetBytes(jsonString);
            var stream = new MemoryStream(bytes);

            var buffer = new byte[4096];

            // Fill the buffer.
            // For this snippet, we're assuming the stream is open and has data.
            // If it might be closed or empty, check if the return value is 0.
            stream.Read(buffer);

            var reader = new Utf8JsonReader(buffer, isFinalBlock: false, state: default);
            Console.WriteLine($"String in buffer is: {Encoding.UTF8.GetString(buffer)}");

            // Search for "Summary" property name
            while (reader.TokenType != JsonTokenType.PropertyName || !reader.ValueTextEquals("Summary"))
            {
                if (!reader.Read())
                {
                    // Not enough of the JSON is in the buffer to complete a read.
                    GetMoreBytesFromStream(stream, ref buffer, ref reader);
                }
            }

            // Found the "Summary" property name.
            Console.WriteLine($"String in buffer is: {Encoding.UTF8.GetString(buffer)}");
            while (!reader.Read())
            {
                // Not enough of the JSON is in the buffer to complete a read.
                GetMoreBytesFromStream(stream, ref buffer, ref reader);
            }
            // Display value of Summary property, that is, "Hot".
            Console.WriteLine($"Got property value: {reader.GetString()}");
        }

        private static void GetMoreBytesFromStream(MemoryStream stream, ref byte[] buffer, ref Utf8JsonReader reader)
        {
            int bytesRead;
            if (reader.BytesConsumed < buffer.Length)
            {
                ReadOnlySpan<byte> leftover = buffer.AsSpan((int)reader.BytesConsumed);

                if (leftover.Length == buffer.Length)
                {
                    Array.Resize(ref buffer, buffer.Length * 2);
                    Console.WriteLine($"Increased buffer size to {buffer.Length}");
                }

                leftover.CopyTo(buffer);
                bytesRead = stream.Read(buffer.AsSpan(leftover.Length));
            }
            else
            {
                bytesRead = stream.Read(buffer);
            }
            Console.WriteLine($"String in buffer is: {Encoding.UTF8.GetString(buffer)}");
            reader = new Utf8JsonReader(buffer, isFinalBlock: bytesRead == 0, reader.CurrentState);
        }
    }
}

O exemplo anterior não define nenhum limite quanto ao tamanho do buffer pode crescer.The preceding example sets no limit to how big the buffer can grow. Se o tamanho do token for muito grande, o código poderá falhar com uma OutOfMemoryException exceção.If the token size is too large, the code could fail with an OutOfMemoryException exception. Isso pode acontecer se o JSON contiver um token com cerca de 1 GB ou mais de tamanho, porque dobrar o tamanho de 1 GB resulta em um tamanho muito grande para caber em um int32 buffer.This can happen if the JSON contains a token that is around 1 GB or more in size, because doubling the 1 GB size results in a size that is too large to fit into an int32 buffer.

Recursos adicionaisAdditional resources