Como migrar do Newtonsoft.Json para oSystem.Text.JsonHow to migrate from Newtonsoft.Json to System.Text.Json

Este artigo mostra como migrar do Newtonsoft.Json para o System.Text.Json .This article shows how to migrate from Newtonsoft.Json to System.Text.Json.

O System.Text.Json namespace fornece a funcionalidade para serializar e desserializar de JavaScript Object Notation (JSON).The System.Text.Json namespace provides functionality for serializing to and deserializing from JavaScript Object Notation (JSON). A System.Text.Json biblioteca está incluída na estrutura compartilhada do .net Core 3,0 .The System.Text.Json library is included in the .NET Core 3.0 shared framework. Para outras estruturas de destino, instale o System.Text.Json pacote NuGet.For other target frameworks, install the System.Text.Json NuGet package. O pacote dá suporte a:The package supports:

  • .NET Standard 2,0 e versões posteriores.NET Standard 2.0 and later versions
  • .NET Framework 4.7.2 e versões posteriores.NET Framework 4.7.2 and later versions
  • .NET Core 2,0, 2,1 e 2,2.NET Core 2.0, 2.1, and 2.2

System.Text.Jsonconcentra-se principalmente em desempenho, segurança e conformidade de padrões.System.Text.Json focuses primarily on performance, security, and standards compliance. Ele tem algumas diferenças importantes no comportamento padrão e não tem como objetivo ter paridade de recursos com o Newtonsoft.Json .It has some key differences in default behavior and doesn't aim to have feature parity with Newtonsoft.Json. Para alguns cenários, o System.Text.Json não tem funcionalidade interna, mas há soluções alternativas recomendadas.For some scenarios, System.Text.Json has no built-in functionality, but there are recommended workarounds. Para outros cenários, as soluções alternativas são impraticável.For other scenarios, workarounds are impractical. Se seu aplicativo depende de um recurso ausente, considere o arquivamento de um problema para descobrir se o suporte para seu cenário pode ser adicionado.If your application depends on a missing feature, consider filing an issue to find out if support for your scenario can be added.

A maior parte deste artigo é sobre como usar a JsonSerializer API, mas também inclui orientação sobre como usar o JsonDocument (que representa os tipos modelo de objeto do documento ou dom), Utf8JsonReader e Utf8JsonWriter .Most of this article is about how to use the JsonSerializer API, but it also includes guidance on how to use the JsonDocument (which represents the Document Object Model or DOM), Utf8JsonReader, and Utf8JsonWriter types.

Tabela de diferenças entre Newtonsoft.Json eSystem.Text.JsonTable of differences between Newtonsoft.Json and System.Text.Json

A tabela a seguir lista os Newtonsoft.Json recursos e System.Text.Json equivalentes.The following table lists Newtonsoft.Json features and System.Text.Json equivalents. Os equivalentes se enquadram nas seguintes categorias:The equivalents fall into the following categories:

  • Com suporte pela funcionalidade interna.Supported by built-in functionality. Obter comportamento semelhante do System.Text.Json pode exigir o uso de um atributo ou uma opção global.Getting similar behavior from System.Text.Json may require the use of an attribute or global option.
  • Sem suporte, a solução alternativa é possível.Not supported, workaround is possible. As soluções alternativas são conversores personalizados, que podem não fornecer paridade completa com Newtonsoft.Json funcionalidade.The workarounds are custom converters, which may not provide complete parity with Newtonsoft.Json functionality. Para alguns deles, o código de exemplo é fornecido como exemplos.For some of these, sample code is provided as examples. Se você depender desses Newtonsoft.Json recursos, a migração exigirá modificações em seus modelos de objeto .net ou em outras alterações de código.If you rely on these Newtonsoft.Json features, migration will require modifications to your .NET object models or other code changes.
  • Sem suporte, a solução alternativa não é prática ou possível.Not supported, workaround is not practical or possible. Se você depender desses Newtonsoft.Json recursos, a migração não será possível sem alterações significativas.If you rely on these Newtonsoft.Json features, migration will not be possible without significant changes.
Recurso do Newtonsoft.JsonNewtonsoft.Json feature System.Text.Jsonequivalente equivalent
Desserialização não diferencia maiúsculas de minúsculas por padrãoCase-insensitive deserialization by default configuração global do ✔️ PropertyNameCaseInsensitive✔️ PropertyNameCaseInsensitive global setting
Nomes de Propriedade do camel caseCamel-case property names configuração global do ✔️ PropertyNamingPolicy✔️ PropertyNamingPolicy global setting
Escape de caractere mínimoMinimal character escaping ✔️ escape de caractere estrito, configurável✔️ Strict character escaping, configurable
NullValueHandling.Ignoreconfiguração globalNullValueHandling.Ignore global setting ✔️ opção global IgnoreNullValues✔️ IgnoreNullValues global option
Permitir comentáriosAllow comments configuração global do ✔️ ReadCommentHandling✔️ ReadCommentHandling global setting
Permitir vírgulas à direitaAllow trailing commas configuração global do ✔️ AllowTrailingCommas✔️ AllowTrailingCommas global setting
Registro do conversor personalizadoCustom converter registration ✔️ ordem de precedência difere✔️ Order of precedence differs
Sem profundidade máxima por padrãoNo maximum depth by default ✔️ profundidade máxima padrão 64, configurável✔️ Default maximum depth 64, configurable
Suporte para uma ampla variedade de tiposSupport for a broad range of types ⚠️Alguns tipos exigem conversores personalizados⚠️ Some types require custom converters
Desserializar cadeias de caracteres como númerosDeserialize strings as numbers ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
Desserializar Dictionary com chave não cadeia de caracteresDeserialize Dictionary with non-string key ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
Serialização polimórficaPolymorphic serialization ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
Desserialização polimórficaPolymorphic deserialization ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
Desserializar tipo inferido para object PropriedadesDeserialize inferred type to object properties ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
Desserializar null literal JSON para tipos de valores não anuláveisDeserialize JSON null literal to non-nullable value types ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
Desserializar para classes e structs imutáveisDeserialize to immutable classes and structs ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
Atributo [JsonConstructor][JsonConstructor] attribute ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
RequiredConfigurando no [JsonProperty] atributoRequired setting on [JsonProperty] attribute ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
NullValueHandlingConfigurando no [JsonProperty] atributoNullValueHandling setting on [JsonProperty] attribute ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
DefaultValueHandlingConfigurando no [JsonProperty] atributoDefaultValueHandling setting on [JsonProperty] attribute ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
DefaultValueHandlingconfiguração globalDefaultValueHandling global setting ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
DefaultContractResolverpara excluir propriedadesDefaultContractResolver to exclude properties ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
DateTimeZoneHandling, DateFormatString configuraçõesDateTimeZoneHandling, DateFormatString settings ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
Retornos de chamadaCallbacks ⚠️Sem suporte, solução alternativa, exemplo⚠️ Not supported, workaround, sample
Suporte para campos públicos e não públicosSupport for public and non-public fields ⚠️Sem suporte, solução alternativa⚠️ Not supported, workaround
Suporte para setters e getters de propriedade interna e privadaSupport for internal and private property setters and getters ⚠️Sem suporte, solução alternativa⚠️ Not supported, workaround
Método JsonConvert.PopulateObjectJsonConvert.PopulateObject method ⚠️Sem suporte, solução alternativa⚠️ Not supported, workaround
ObjectCreationHandlingconfiguração globalObjectCreationHandling global setting ⚠️Sem suporte, solução alternativa⚠️ Not supported, workaround
Adicionar a coleções sem settersAdd to collections without setters ⚠️Sem suporte, solução alternativa⚠️ Not supported, workaround
PreserveReferencesHandlingconfiguração globalPreserveReferencesHandling global setting Sem suporteNot supported
ReferenceLoopHandlingconfiguração globalReferenceLoopHandling global setting Sem suporteNot supported
Suporte para System.Runtime.Serialization atributosSupport for System.Runtime.Serialization attributes Sem suporteNot supported
MissingMemberHandlingconfiguração globalMissingMemberHandling global setting Sem suporteNot supported
Permitir nomes de propriedade sem aspasAllow property names without quotes Sem suporteNot supported
Permitir aspas simples em vez de valores de cadeia de caracteresAllow single quotes around string values Sem suporteNot supported
Permitir valores JSON que não são de cadeia de caracteres para propriedades de cadeia de caracteresAllow non-string JSON values for string properties Sem suporteNot supported

Esta não é uma lista completa de Newtonsoft.Json recursos.This is not an exhaustive list of Newtonsoft.Json features. A lista inclui muitos dos cenários que foram solicitados em problemas do GitHub ou postagens do StackOverflow .The list includes many of the scenarios that have been requested in GitHub issues or StackOverflow posts. Se você implementar uma solução alternativa para um dos cenários listados aqui que não tem um código de exemplo, e se você quiser compartilhar sua solução, selecione esta página na seção de comentários na parte inferior desta página.If you implement a workaround for one of the scenarios listed here that doesn't currently have sample code, and if you want to share your solution, select This page in the Feedback section at the bottom of this page. Isso cria um problema no repositório GitHub da documentação e o lista na seção de comentários nesta página também.That creates an issue in this documentation's GitHub repo and lists it in the Feedback section on this page too.

Diferenças no comportamento padrão de JsonSerializer em comparação comNewtonsoft.JsonDifferences in default JsonSerializer behavior compared to Newtonsoft.Json

System.Text.Jsoné estrito por padrão e evita qualquer adivinhação ou interpretação em nome do chamador, enfatizando o comportamento determinístico.System.Text.Json is strict by default and avoids any guessing or interpretation on the caller's behalf, emphasizing deterministic behavior. A biblioteca foi projetada intencionalmente dessa forma para desempenho e segurança.The library is intentionally designed this way for performance and security. Newtonsoft.Jsoné flexível por padrão.Newtonsoft.Json is flexible by default. Essa diferença fundamental no design está por trás de muitas das diferenças específicas a seguir no comportamento padrão.This fundamental difference in design is behind many of the following specific differences in default behavior.

Desserialização não diferencia maiúsculas de minúsculasCase-insensitive deserialization

Durante a desserialização, Newtonsoft.Json o nome da propriedade que não diferencia maiúsculas de minúsculas corresponde por padrão.During deserialization, Newtonsoft.Json does case-insensitive property name matching by default. O System.Text.Json padrão diferencia maiúsculas de minúsculas, o que proporciona melhor desempenho, pois está fazendo uma correspondência exata.The System.Text.Json default is case-sensitive, which gives better performance since it's doing an exact match. Para obter informações sobre como fazer a correspondência que não diferencia maiúsculas de minúsculas, consulte correspondência de propriedadeque não diferencia maiúsculas de minúsculas.For information about how to do case-insensitive matching, see Case-insensitive property matching.

Se você estiver usando System.Text.Json indiretamente usando ASP.NET Core, não precisará fazer nada para obter o comportamento como Newtonsoft.Json .If you're using System.Text.Json indirectly by using ASP.NET Core, you don't need to do anything to get behavior like Newtonsoft.Json. ASP.NET Core especifica as configurações para os nomes de Propriedade do Camel case e a correspondência que não diferencia maiúsculas de minúsculas quando ela usa System.Text.Json .ASP.NET Core specifies the settings for camel-casing property names and case-insensitive matching when it uses System.Text.Json.

Escape de caractere mínimoMinimal character escaping

Durante a serialização, Newtonsoft.Json é relativamente permissivo de permitir caracteres sem escape.During serialization, Newtonsoft.Json is relatively permissive about letting characters through without escaping them. Ou seja, ele não os substitui por \uxxxx Where xxxx é o ponto de código do caractere.That is, it doesn't replace them with \uxxxx where xxxx is the character's code point. Em que ele faz escape, ele faz isso emitindo um \ antes do caractere (por exemplo, " se torna \" ).Where it does escape them, it does so by emitting a \ before the character (for example, " becomes \"). System.Text.Jsonescapa mais caracteres por padrão para fornecer proteções de defesa profunda contra XSS (script entre sites) ou ataques de divulgação de informações e faz isso usando a sequência de seis caracteres.System.Text.Json escapes more characters by default to provide defense-in-depth protections against cross-site scripting (XSS) or information-disclosure attacks and does so by using the six-character sequence. System.Text.Jsonescapa todos os caracteres não ASCII por padrão, portanto, você não precisa fazer nada se estiver usando o StringEscapeHandling.EscapeNonAscii no Newtonsoft.Json .System.Text.Json escapes all non-ASCII characters by default, so you don't need to do anything if you're using StringEscapeHandling.EscapeNonAscii in Newtonsoft.Json. System.Text.Jsontambém escapa caracteres com distinção de HTML, por padrão.System.Text.Json also escapes HTML-sensitive characters, by default. Para obter informações sobre como substituir o System.Text.Json comportamento padrão, consulte Personalizar codificação de caracteres.For information about how to override the default System.Text.Json behavior, see Customize character encoding.

ComentáriosComments

Durante a desserialização, o Newtonsoft.Json ignora comentários no JSON por padrão.During deserialization, Newtonsoft.Json ignores comments in the JSON by default. O System.Text.Json padrão é gerar exceções para comentários porque a especificação RFC 8259 não os inclui.The System.Text.Json default is to throw exceptions for comments because the RFC 8259 specification doesn't include them. Para obter informações sobre como permitir comentários, consulte permitir comentários e vírgulas à direita.For information about how to allow comments, see Allow comments and trailing commas.

Vírgula à direitaTrailing commas

Durante a desserialização, o Newtonsoft.Json ignora vírgulas à direita por padrão.During deserialization, Newtonsoft.Json ignores trailing commas by default. Ele também ignora várias vírgulas à direita (por exemplo, [{"Color":"Red"},{"Color":"Green"},,] ).It also ignores multiple trailing commas (for example, [{"Color":"Red"},{"Color":"Green"},,]). O System.Text.Json padrão é lançar exceções para vírgulas à direita porque a especificação RFC 8259 não as permite.The System.Text.Json default is to throw exceptions for trailing commas because the RFC 8259 specification doesn't allow them. Para obter informações sobre como fazer com que System.Text.Json sejam aceitas, consulte permitir comentários e vírgulas à direita.For information about how to make System.Text.Json accept them, see Allow comments and trailing commas. Não há como permitir várias vírgulas à direita.There's no way to allow multiple trailing commas.

Precedência de registro do conversorConverter registration precedence

A Newtonsoft.Json precedência de registro para conversores personalizados é a seguinte:The Newtonsoft.Json registration precedence for custom converters is as follows:

  • Atributo na propriedadeAttribute on property
  • Atributo no tipoAttribute on type
  • Coleção de conversoresConverters collection

Essa ordem significa que um conversor personalizado na Converters coleção é substituído por um conversor registrado pela aplicação de um atributo no nível de tipo.This order means that a custom converter in the Converters collection is overridden by a converter that is registered by applying an attribute at the type level. Ambos os registros são substituídos por um atributo no nível de propriedade.Both of those registrations are overridden by an attribute at the property level.

A System.Text.Json precedência de registro para conversores personalizados é diferente:The System.Text.Json registration precedence for custom converters is different:

  • Atributo na propriedadeAttribute on property
  • ConvertersColeConverters collection
  • Atributo no tipoAttribute on type

A diferença aqui é que um conversor personalizado na Converters coleção substitui um atributo no nível de tipo.The difference here is that a custom converter in the Converters collection overrides an attribute at the type level. A intenção por trás dessa ordem de precedência é fazer com que as alterações em tempo de execução substituam as opções de tempo de design.The intention behind this order of precedence is to make run-time changes override design-time choices. Não há como alterar a precedência.There's no way to change the precedence.

Para obter mais informações sobre o registro de conversor personalizado, consulte registrar um conversor personalizado.For more information about custom converter registration, see Register a custom converter.

Profundidade máximaMaximum depth

Newtonsoft.JsonNão tem um limite de profundidade máximo por padrão.Newtonsoft.Json doesn't have a maximum depth limit by default. System.Text.JsonHá um limite padrão de 64 e é configurável pela configuração JsonSerializerOptions.MaxDepth .For System.Text.Json there's a default limit of 64, and it's configurable by setting JsonSerializerOptions.MaxDepth.

Cadeias JSON (nomes de propriedade e valores de cadeia de caracteres)JSON strings (property names and string values)

Durante a desserialização, o Newtonsoft.Json aceita nomes de propriedade entre aspas duplas, aspas simples ou sem aspas.During deserialization, Newtonsoft.Json accepts property names surrounded by double quotes, single quotes, or without quotes. Ele aceita valores de cadeia de caracteres entre aspas duplas ou aspas simples.It accepts string values surrounded by double quotes or single quotes. Por exemplo, Newtonsoft.Json aceita o seguinte JSON:For example, Newtonsoft.Json accepts the following JSON:

{
  "name1": "value",
  'name2': "value",
  name3: 'value'
}

System.Text.Jsonaceita somente nomes de propriedade e valores de cadeia de caracteres entre aspas duplas porque esse formato é exigido pela especificação RFC 8259 e é o único formato considerado JSON válido.System.Text.Json only accepts property names and string values in double quotes because that format is required by the RFC 8259 specification and is the only format considered valid JSON.

Um valor entre aspas simples resulta em uma jsonexception com a seguinte mensagem:A value enclosed in single quotes results in a JsonException with the following message:

''' is an invalid start of a value.

Valores que não são de cadeia de caracteres para propriedades de cadeia de caracteresNon-string values for string properties

Newtonsoft.Jsonaceita valores que não são de cadeia de caracteres, como um número ou literais true e false , para desserialização para propriedades do tipo cadeia de caracteres.Newtonsoft.Json accepts non-string values, such as a number or the literals true and false, for deserialization to properties of type string. Aqui está um exemplo de JSON que é Newtonsoft.Json desserializado com êxito para a seguinte classe:Here's an example of JSON that Newtonsoft.Json successfully deserializes to the following class:

{
  "String1": 1,
  "String2": true,
  "String3": false
}
public class ExampleClass
{
    public string String1 { get; set; }
    public string String2 { get; set; }
    public string String3 { get; set; }
}

System.Text.JsonNão desserializa os valores que não são de cadeia de caracteres em Propriedades de cadeia de caracteres.System.Text.Json doesn't deserialize non-string values into string properties. Um valor de não cadeia de caracteres recebido para um campo de cadeia de caracteres resulta em uma jsonexception com a seguinte mensagem:A non-string value received for a string field results in a JsonException with the following message:

The JSON value could not be converted to System.String.

Cenários que usam JsonSerializer que exigem soluções alternativasScenarios using JsonSerializer that require workarounds

Os cenários a seguir não têm suporte da funcionalidade interna, mas as soluções alternativas são possíveis.The following scenarios aren't supported by built-in functionality, but workarounds are possible. As soluções alternativas são conversores personalizados, que podem não fornecer paridade completa com Newtonsoft.Json funcionalidade.The workarounds are custom converters, which may not provide complete parity with Newtonsoft.Json functionality. Para alguns deles, o código de exemplo é fornecido como exemplos.For some of these, sample code is provided as examples. Se você depender desses Newtonsoft.Json recursos, a migração exigirá modificações em seus modelos de objeto .net ou em outras alterações de código.If you rely on these Newtonsoft.Json features, migration will require modifications to your .NET object models or other code changes.

Tipos sem suporte internoTypes without built-in support

System.Text.Jsono não fornece suporte interno para os seguintes tipos:System.Text.Json doesn't provide built-in support for the following types:

Conversores personalizados podem ser implementados para tipos que não têm suporte interno.Custom converters can be implemented for types that don't have built-in support.

Números entre aspasQuoted numbers

Newtonsoft.Jsonpode serializar ou desserializar números representados por cadeias de caracteres JSON (entre aspas).Newtonsoft.Json can serialize or deserialize numbers represented by JSON strings (surrounded by quotes). Por exemplo, ele pode aceitar: {"DegreesCelsius":"23"} em vez de {"DegreesCelsius":23} .For example, it can accept: {"DegreesCelsius":"23"} instead of {"DegreesCelsius":23}. Para habilitar esse comportamento no System.Text.Json , implemente um conversor personalizado como o exemplo a seguir.To enable that behavior in System.Text.Json, implement a custom converter like the following example. O conversor manipula as propriedades definidas como long :The converter handles properties defined as long:

  • Ele os serializa como cadeias de caracteres JSON.It serializes them as JSON strings.
  • Ele aceita números JSON e números entre aspas durante a desserialização.It accepts JSON numbers and numbers within quotes while deserializing.
using System;
using System.Buffers;
using System.Buffers.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace SystemTextJsonSamples
{
    public class LongToStringConverter : JsonConverter<long>
    {
        public override long Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options)
        {
            if (reader.TokenType == JsonTokenType.String)
            {
                ReadOnlySpan<byte> span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan;
                if (Utf8Parser.TryParse(span, out long number, out int bytesConsumed) && span.Length == bytesConsumed)
                    return number;

                if (Int64.TryParse(reader.GetString(), out number))
                    return number;
            }

            return reader.GetInt64();
        }

        public override void Write(Utf8JsonWriter writer, long longValue, JsonSerializerOptions options)
        {
            writer.WriteStringValue(longValue.ToString());
        }
    }
}

Registre esse conversor personalizado usando um atributo em propriedades individuais long ou adicionando o conversor à Converters coleção.Register this custom converter by using an attribute on individual long properties or by adding the converter to the Converters collection.

Dicionário com chave não cadeia de caracteresDictionary with non-string key

Newtonsoft.Jsondá suporte a coleções do tipo Dictionary<TKey, TValue> .Newtonsoft.Json supports collections of type Dictionary<TKey, TValue>. O suporte interno para coleções de dicionário no System.Text.Json é limitado ao Dictionary<string, TValue> .The built-in support for dictionary collections in System.Text.Json is limited to Dictionary<string, TValue>. Ou seja, a chave deve ser uma cadeia de caracteres.That is, the key must be a string.

Para dar suporte a um dicionário com um inteiro ou algum outro tipo como a chave, crie um conversor como o exemplo em como escrever conversores personalizados.To support a dictionary with an integer or some other type as the key, create a converter like the example in How to write custom converters.

Serialização polimórficaPolymorphic serialization

Newtonsoft.Jsonautomaticamente a serialização polimórfica.Newtonsoft.Json automatically does polymorphic serialization. Para obter informações sobre os recursos limitados de serialização polimórfico do System.Text.Json , consulte serializar Propriedades de classes derivadas.For information about the limited polymorphic serialization capabilities of System.Text.Json, see Serialize properties of derived classes.

A solução alternativa descrita aqui é definir as propriedades que podem conter classes derivadas como tipo object .The workaround described there is to define properties that may contain derived classes as type object. Se isso não for possível, outra opção é criar um conversor com um Write método para a hierarquia de tipo de herança inteira, como o exemplo em como escrever conversores personalizados.If that isn't possible, another option is to create a converter with a Write method for the whole inheritance type hierarchy like the example in How to write custom converters.

Desserialização polimórficaPolymorphic deserialization

Newtonsoft.Jsontem uma TypeNameHandling configuração que adiciona metadados de nome de tipo ao JSON durante a serialização.Newtonsoft.Json has a TypeNameHandling setting that adds type name metadata to the JSON while serializing. Ele usa os metadados durante a desserialização para fazer a desserialização polimórfica.It uses the metadata while deserializing to do polymorphic deserialization. System.Text.Jsonpode fazer um intervalo limitado de serialização polimórfica , mas não desserialização polimórfica.System.Text.Json can do a limited range of polymorphic serialization but not polymorphic deserialization.

Para dar suporte à desserialização polimórfica, crie um conversor como o exemplo em como escrever conversores personalizados.To support polymorphic deserialization, create a converter like the example in How to write custom converters.

Desserialização de propriedades de objetoDeserialization of object properties

Quando o Newtonsoft.Json desserializa para Object , ele:When Newtonsoft.Json deserializes to Object, it:

  • Infere o tipo de valores primitivos no conteúdo JSON (diferente de null ) e retorna o armazenado string , long , double , boolean ou DateTime como um objeto em caixa.Infers the type of primitive values in the JSON payload (other than null) and returns the stored string, long, double, boolean, or DateTime as a boxed object. Os valores primitivos são valores JSON únicos, como um número JSON, Cadeia de caracteres,, true false ou null .Primitive values are single JSON values such as a JSON number, string, true, false, or null.
  • Retorna um JObject ou JArray para valores complexos na carga JSON.Returns a JObject or JArray for complex values in the JSON payload. Valores complexos são coleções de pares chave-valor JSON entre chaves ( {} ) ou listas de valores entre colchetes ( [] ).Complex values are collections of JSON key-value pairs within braces ({}) or lists of values within brackets ([]). As propriedades e os valores dentro das chaves ou colchetes podem ter propriedades ou valores adicionais.The properties and values within the braces or brackets can have additional properties or values.
  • Retorna uma referência nula quando a carga tem o null literal JSON.Returns a null reference when the payload has the null JSON literal.

System.Text.JsonArmazena um Boxed JsonElement para valores primitivos e complexos sempre que a desserialização para Object , por exemplo:System.Text.Json stores a boxed JsonElement for both primitive and complex values whenever deserializing to Object, for example:

  • Uma object propriedade.An object property.
  • Um object valor de dicionário.An object dictionary value.
  • Um object valor de matriz.An object array value.
  • Uma raiz object .A root object.

No entanto, System.Text.Json null o trata o mesmo que Newtonsoft.Json e retorna uma referência nula quando a carga tem o null literal JSON nela.However, System.Text.Json treats null the same as Newtonsoft.Json and returns a null reference when the payload has the null JSON literal in it.

Para implementar a inferência de tipos para object Propriedades, crie um conversor como o exemplo em como escrever conversores personalizados.To implement type inference for object properties, create a converter like the example in How to write custom converters.

Desserializar NULL para tipo não anulávelDeserialize null to non-nullable type

Newtonsoft.Jsono não gera uma exceção no cenário a seguir:Newtonsoft.Json doesn't throw an exception in the following scenario:

  • NullValueHandlingé definido como Ignore eNullValueHandling is set to Ignore, and
  • Durante a desserialização, o JSON contém um valor nulo para um tipo de valor não anulável.During deserialization, the JSON contains a null value for a non-nullable value type.

No mesmo cenário, o System.Text.Json gera uma exceção.In the same scenario, System.Text.Json does throw an exception. (A configuração de manipulação nula correspondente é JsonSerializerOptions.IgnoreNullValues .)(The corresponding null handling setting is JsonSerializerOptions.IgnoreNullValues.)

Se você possui o tipo de destino, a melhor solução alternativa é tornar a propriedade em questão anulável (por exemplo, alterar int para int? ).If you own the target type, the best workaround is to make the property in question nullable (for example, change int to int?).

Outra solução alternativa é criar um conversor para o tipo, como o exemplo a seguir, que manipula valores nulos para DateTimeOffset tipos:Another workaround is to make a converter for the type, such as the following example that handles null values for DateTimeOffset types:

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

namespace SystemTextJsonSamples
{
    public class DateTimeOffsetNullHandlingConverter : JsonConverter<DateTimeOffset>

    {
        public override DateTimeOffset Read(
            ref Utf8JsonReader reader,
            Type typeToConvert,
            JsonSerializerOptions options)
        {
            if (reader.TokenType == JsonTokenType.Null)
            {
                return default;
            }
            return reader.GetDateTimeOffset();
        }

        public override void Write(
            Utf8JsonWriter writer,
            DateTimeOffset dateTimeValue,
            JsonSerializerOptions options)
        {
            writer.WriteStringValue(dateTimeValue);
        }
    }
}

Registre esse conversor personalizado usando um atributo na propriedade ou adicionando o conversor à Converters coleção.Register this custom converter by using an attribute on the property or by adding the converter to the Converters collection.

Observação: O conversor anterior manipula valores nulos de forma diferente Newtonsoft.Json do que o faz para POCOs que especificam valores padrão.Note: The preceding converter handles null values differently than Newtonsoft.Json does for POCOs that specify default values. 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 usando o conversor anterior:And suppose the following JSON is deserialized by using the preceding converter:

{
  "Date": null,
  "TemperatureCelsius": 25,
  "Summary": null
}

Após a desserialização, a Date propriedade tem 1/1/0001 ( default(DateTimeOffset) ), ou seja, o valor definido no construtor é substituído.After deserialization, the Date property has 1/1/0001 (default(DateTimeOffset)), that is, the value set in the constructor is overwritten. Considerando o mesmo POCO e JSON, a Newtonsoft.Json desserialização deixaria 1/1/2001 na Date propriedade.Given the same POCO and JSON, Newtonsoft.Json deserialization would leave 1/1/2001 in the Date property.

Desserializar para classes e structs imutáveisDeserialize to immutable classes and structs

Newtonsoft.Jsonpode desserializar para classes e structs imutáveis porque pode usar construtores com parâmetros.Newtonsoft.Json can deserialize to immutable classes and structs because it can use constructors that have parameters. System.Text.Jsondá suporte apenas a construtores públicos sem parâmetros.System.Text.Json supports only public parameterless constructors. Como alternativa, você pode chamar um construtor com parâmetros em um conversor personalizado.As a workaround, you can call a constructor with parameters in a custom converter.

Aqui está um struct imutável com vários parâmetros de construtor:Here's an immutable struct with multiple constructor parameters:

public readonly struct ImmutablePoint
{
    public ImmutablePoint(int x, int y)
    {
        X = x;
        Y = y;
    }

    public int X { get; }
    public int Y { get; }
}

E aqui está um conversor que serializa e desserializa essa estrutura:And here's a converter that serializes and deserializes this struct:

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

namespace SystemTextJsonSamples
{
    public class ImmutablePointConverter : JsonConverter<ImmutablePoint>
    {
        private readonly JsonEncodedText XName = JsonEncodedText.Encode("X");
        private readonly JsonEncodedText YName = JsonEncodedText.Encode("Y");

        private readonly JsonConverter<int> _intConverter;

        public ImmutablePointConverter(JsonSerializerOptions options)
        {
            if (options?.GetConverter(typeof(int)) is JsonConverter<int> intConverter)
            {
                _intConverter = intConverter;
            }
            else
            {
                throw new InvalidOperationException();
            }
        }

        public override ImmutablePoint Read(
            ref Utf8JsonReader reader,
            Type typeToConvert,
            JsonSerializerOptions options)
        {
            if (reader.TokenType != JsonTokenType.StartObject)
            {
                throw new JsonException();
            };

            int x = default;
            bool xSet = false;

            int y = default;
            bool ySet = false;

            // Get the first property.
            reader.Read();
            if (reader.TokenType != JsonTokenType.PropertyName)
            {
                throw new JsonException();
            }

            if (reader.ValueTextEquals(XName.EncodedUtf8Bytes))
            {
                x = ReadProperty(ref reader, options);
                xSet = true;
            }
            else if (reader.ValueTextEquals(YName.EncodedUtf8Bytes))
            {
                y = ReadProperty(ref reader, options);
                ySet = true;
            }
            else
            {
                throw new JsonException();
            }

            // Get the second property.
            reader.Read();
            if (reader.TokenType != JsonTokenType.PropertyName)
            {
                throw new JsonException();
            }

            if (xSet && reader.ValueTextEquals(YName.EncodedUtf8Bytes))
            {
                y = ReadProperty(ref reader, options);
            }
            else if (ySet && reader.ValueTextEquals(XName.EncodedUtf8Bytes))
            {
                x = ReadProperty(ref reader, options);
            }
            else
            {
                throw new JsonException();
            }

            reader.Read();

            if (reader.TokenType != JsonTokenType.EndObject)
            {
                throw new JsonException();
            }

            return new ImmutablePoint(x, y);
        }

        private int ReadProperty(ref Utf8JsonReader reader, JsonSerializerOptions options)
        {
            Debug.Assert(reader.TokenType == JsonTokenType.PropertyName);

            reader.Read();
            return _intConverter.Read(ref reader, typeof(int), options);
        }

        private void WriteProperty(Utf8JsonWriter writer, JsonEncodedText name, int intValue, JsonSerializerOptions options)
        {
            writer.WritePropertyName(name);
            _intConverter.Write(writer, intValue, options);
        }

        public override void Write(
            Utf8JsonWriter writer,
            ImmutablePoint point,
            JsonSerializerOptions options)
        {
            writer.WriteStartObject();
            WriteProperty(writer, XName, point.X, options);
            WriteProperty(writer, YName, point.Y, options);
            writer.WriteEndObject();
        }
    }
}

Registre esse conversor personalizado adicionando o conversor à Converters coleção.Register this custom converter by adding the converter to the Converters collection.

Para obter um exemplo de um conversor semelhante que manipula propriedades genéricas abertas, consulte o conversor interno para pares de chave-valor.For an example of a similar converter that handles open generic properties, see the built-in converter for key-value pairs.

Especificar o Construtor a ser usadoSpecify constructor to use

O Newtonsoft.Json [JsonConstructor] atributo permite que você especifique qual Construtor chamar ao desserializar para um poco.The Newtonsoft.Json [JsonConstructor] attribute lets you specify which constructor to call when deserializing to a POCO. System.Text.Jsondá suporte apenas a construtores sem parâmetros.System.Text.Json supports only parameterless constructors. Como alternativa, você pode chamar qualquer Construtor necessário em um conversor personalizado.As a workaround, you can call whichever constructor you need in a custom converter. Consulte o exemplo para desserializar classes e structs imutáveis.See the example for Deserialize to immutable classes and structs.

Propriedades obrigatóriasRequired properties

No Newtonsoft.Json , você especifica que uma propriedade é exigida pela configuração Required no [JsonProperty] atributo.In Newtonsoft.Json, you specify that a property is required by setting Required on the [JsonProperty] attribute. Newtonsoft.Jsongera uma exceção se nenhum valor for recebido no JSON para uma propriedade marcada como necessária.Newtonsoft.Json throws an exception if no value is received in the JSON for a property marked as required.

System.Text.JsonNão lançará uma exceção se nenhum valor for recebido para uma das propriedades do tipo de destino.System.Text.Json doesn't throw an exception if no value is received for one of the properties of the target type. Por exemplo, se você tiver uma WeatherForecast classe:For example, if you have a WeatherForecast class:

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

O JSON a seguir é desserializado sem erro:The following JSON is deserialized without error:

{
    "TemperatureCelsius": 25,
    "Summary": "Hot"
}

Para fazer a desserialização falhar se nenhuma Date propriedade estiver no JSON, implemente um conversor personalizado.To make deserialization fail if no Date property is in the JSON, implement a custom converter. O código de conversor de exemplo a seguir gera uma exceção se a Date propriedade não estiver definida após a desserialização ser concluída:The following sample converter code throws an exception if the Date property isn't set after deserialization is complete:

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

namespace SystemTextJsonSamples
{
    public class WeatherForecastRequiredPropertyConverter : JsonConverter<WeatherForecast>
    {
        public override WeatherForecast Read(
            ref Utf8JsonReader reader,
            Type type,
            JsonSerializerOptions options)
        {
            // Don't pass in options when recursively calling Deserialize.
            WeatherForecast forecast = JsonSerializer.Deserialize<WeatherForecast>(ref reader);

            // Check for required fields set by values in JSON
            if (forecast.Date == default)
            {
                throw new JsonException("Required property not received in the JSON");
            }
            return forecast;
        }

        public override void Write(
            Utf8JsonWriter writer,
            WeatherForecast forecast, JsonSerializerOptions options)
        {
            // Don't pass in options when recursively calling Serialize.
            JsonSerializer.Serialize(writer, forecast);
        }
    }
}

Registre esse conversor personalizado usando um atributo na classe poco ou adicionando o conversor à Converters coleção.Register this custom converter by using an attribute on the POCO class or by adding the converter to the Converters collection.

Se você seguir esse padrão, não passe o objeto Options ao chamar de forma recursiva Serialize ou Deserialize .If you follow this pattern, don't pass in the options object when recursively calling Serialize or Deserialize. O objeto Options contém a Converters coleção.The options object contains the Converters collection. Se você passá-lo para Serialize ou Deserialize , o conversor personalizado chamará a si mesmo, fazendo um loop infinito que resulta em uma exceção de estouro de pilha.If you pass it in to Serialize or Deserialize, the custom converter calls into itself, making an infinite loop that results in a stack overflow exception. Se as opções padrão não forem viáveis, crie uma nova instância das opções com as configurações necessárias.If the default options are not feasible, create a new instance of the options with the settings that you need. Essa abordagem será lenta, pois cada nova instância armazena em cache de forma independente.This approach will be slow since each new instance caches independently.

O código do conversor anterior é um exemplo simplificado.The preceding converter code is a simplified example. Será necessária uma lógica adicional se você precisar manipular atributos (como [JsonIgnore] ou opções diferentes (como codificadores personalizados).Additional logic would be required if you need to handle attributes (such as [JsonIgnore] or different options (such as custom encoders). Além disso, o código de exemplo não manipula Propriedades para as quais um valor padrão é definido no construtor.Also, the example code doesn't handle properties for which a default value is set in the constructor. E essa abordagem não diferencia os seguintes cenários:And this approach doesn't differentiate between the following scenarios:

  • Uma propriedade está ausente no JSON.A property is missing from the JSON.
  • Uma propriedade para um tipo não anulável está presente no JSON, mas o valor é o padrão para o tipo, como zero para um int .A property for a non-nullable type is present in the JSON, but the value is the default for the type, such as zero for an int.
  • Uma propriedade para um tipo de valor anulável está presente no JSON, mas o valor é NULL.A property for a nullable value type is present in the JSON, but the value is null.

Ignorar condicionalmente uma propriedadeConditionally ignore a property

Newtonsoft.Jsono tem várias maneiras de ignorar condicionalmente uma propriedade na serialização ou desserialização:Newtonsoft.Json has several ways to conditionally ignore a property on serialization or deserialization:

  • DefaultContractResolverpermite selecionar propriedades a serem incluídas ou excluídas, com base em critérios arbitrários.DefaultContractResolver lets you select properties to include or exclude, based on arbitrary criteria.
  • As NullValueHandling DefaultValueHandling configurações e em JsonSerializerSettings permitem que você especifique que todas as propriedades de valor nulo ou valor padrão devem ser ignoradas.The NullValueHandling and DefaultValueHandling settings on JsonSerializerSettings let you specify that all null-value or default-value properties should be ignored.
  • As NullValueHandling DefaultValueHandling configurações e no [JsonProperty] atributo permitem especificar propriedades individuais que devem ser ignoradas quando definidas como NULL ou o valor padrão.The NullValueHandling and DefaultValueHandling settings on the [JsonProperty] attribute let you specify individual properties that should be ignored when set to null or the default value.

System.Text.Jsonfornece as seguintes maneiras de omitir Propriedades ao serializar:System.Text.Json provides the following ways to omit properties while serializing:

  • O atributo [JsonIgnore] em uma propriedade faz com que a propriedade seja omitida do JSON durante a serialização.The [JsonIgnore] attribute on a property causes the property to be omitted from the JSON during serialization.
  • A opção global IgnoreNullValues permite que você exclua todas as propriedades de valor nulo.The IgnoreNullValues global option lets you exclude all null-value properties.
  • A opção global IgnoreReadOnlyProperties permite que você exclua todas as propriedades somente leitura.The IgnoreReadOnlyProperties global option lets you exclude all read-only properties.

Essas opções não permitem que você:These options don't let you:

  • Ignore todas as propriedades que têm o valor padrão para o tipo.Ignore all properties that have the default value for the type.
  • Ignore as propriedades selecionadas que têm o valor padrão para o tipo.Ignore selected properties that have the default value for the type.
  • Ignorar propriedades selecionadas se seu valor for nulo.Ignore selected properties if their value is null.
  • Ignorar as propriedades selecionadas com base em critérios arbitrários avaliados em tempo de execução.Ignore selected properties based on arbitrary criteria evaluated at run time.

Para essa funcionalidade, você pode escrever um conversor personalizado.For that functionality, you can write a custom converter. Aqui está um exemplo de POCO e um conversor personalizado para ele que ilustra essa abordagem:Here's a sample POCO and a custom converter for it that illustrates this approach:

public class WeatherForecast
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
}
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace SystemTextJsonSamples
{
    public class WeatherForecastRuntimeIgnoreConverter : JsonConverter<WeatherForecast>
    {
        public override WeatherForecast Read(
            ref Utf8JsonReader reader,
            Type typeToConvert,
            JsonSerializerOptions options)
        {
            if (reader.TokenType != JsonTokenType.StartObject)
            {
                throw new JsonException();
            }

            var wf = new WeatherForecast();

            while (reader.Read())
            {
                if (reader.TokenType == JsonTokenType.EndObject)
                {
                    return wf;
                }

                if (reader.TokenType == JsonTokenType.PropertyName)
                {
                    string propertyName = reader.GetString();
                    reader.Read();
                    switch (propertyName)
                    {
                        case "Date":
                            DateTimeOffset date = reader.GetDateTimeOffset();
                            wf.Date = date;
                            break;
                        case "TemperatureCelsius":
                            int temperatureCelsius = reader.GetInt32();
                            wf.TemperatureCelsius = temperatureCelsius;
                            break;
                        case "Summary":
                            string summary = reader.GetString();
                            wf.Summary = string.IsNullOrWhiteSpace(summary) ? "N/A" : summary;
                            break;
                    }
                }
            }

            throw new JsonException();
        }

        public override void Write(Utf8JsonWriter writer, WeatherForecast wf, JsonSerializerOptions options)
        {
            writer.WriteStartObject();

            writer.WriteString("Date", wf.Date);
            writer.WriteNumber("TemperatureCelsius", wf.TemperatureCelsius);
            if (!string.IsNullOrWhiteSpace(wf.Summary) && wf.Summary != "N/A")
            {
                writer.WriteString("Summary", wf.Summary);
            }

            writer.WriteEndObject();
        }
    }
}

O conversor faz com que a Summary propriedade seja omitida da serialização se seu valor for NULL, uma cadeia de caracteres vazia ou "N/A".The converter causes the Summary property to be omitted from serialization if its value is null, an empty string, or "N/A".

Registre esse conversor personalizado usando um atributo na classe ou adicionando o conversor à Converters coleção.Register this custom converter by using an attribute on the class or by adding the converter to the Converters collection.

Essa abordagem requer lógica adicional se:This approach requires additional logic if:

  • O POCO inclui propriedades complexas.The POCO includes complex properties.
  • Você precisa manipular atributos como, por [JsonIgnore] exemplo, ou opções como codificadores personalizados.You need to handle attributes such as [JsonIgnore] or options such as custom encoders.

Especificar formato de dataSpecify date format

Newtonsoft.Jsonfornece várias maneiras de controlar como as propriedades DateTime de DateTimeOffset tipos e são serializadas e desserializadas:Newtonsoft.Json provides several ways to control how properties of DateTime and DateTimeOffset types are serialized and deserialized:

  • A DateTimeZoneHandling configuração pode ser usada para serializar todos os DateTime valores como datas UTC.The DateTimeZoneHandling setting can be used to serialize all DateTime values as UTC dates.
  • A DateFormatString configuração e os DateTime conversores podem ser usados para personalizar o formato de cadeias de caracteres de data.The DateFormatString setting and DateTime converters can be used to customize the format of date strings.

No System.Text.Json , o único formato com suporte interno é ISO 8601-1:2019, pois ele é amplamente adotado, não ambíguo e faz viagens de ida e volta com precisão.In System.Text.Json, the only format that has built-in support is ISO 8601-1:2019 since it's widely adopted, unambiguous, and makes round trips precisely. Para usar qualquer outro formato, crie um conversor personalizado.To use any other format, create a custom converter. Para obter mais informações, consulte suporte a DateTime e System.Text.Json DateTimeOffset no .For more information, see DateTime and DateTimeOffset support in System.Text.Json.

Retornos de chamadaCallbacks

Newtonsoft.Jsonpermite executar código personalizado em vários pontos no processo de serialização ou desserialização:Newtonsoft.Json lets you execute custom code at several points in the serialization or deserialization process:

  • OnDeserializing (ao começar a desserializar um objeto)OnDeserializing (when beginning to deserialize an object)
  • OnDeserialized (quando terminar de desserializar um objeto)OnDeserialized (when finished deserializing an object)
  • Onserializando (ao começar a serializar um objeto)OnSerializing (when beginning to serialize an object)
  • OnSerialized (ao concluir a serialização de um objeto)OnSerialized (when finished serializing an object)

No System.Text.Json , você pode simular retornos de chamada escrevendo um conversor personalizado.In System.Text.Json, you can simulate callbacks by writing a custom converter. O exemplo a seguir mostra um conversor personalizado para um POCO.The following example shows a custom converter for a POCO. O conversor inclui um código que exibe uma mensagem em cada ponto correspondente a um Newtonsoft.Json retorno de chamada.The converter includes code that displays a message at each point that corresponds to a Newtonsoft.Json callback.

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

namespace SystemTextJsonSamples
{
    public class WeatherForecastCallbacksConverter : JsonConverter<WeatherForecast>
    {
        public override WeatherForecast Read(
            ref Utf8JsonReader reader,
            Type type,
            JsonSerializerOptions options)
        {
            // Place "before" code here (OnDeserializing),
            // but note that there is no access here to the POCO instance.
            Console.WriteLine("OnDeserializing");

            // Don't pass in options when recursively calling Deserialize.
            WeatherForecast forecast = JsonSerializer.Deserialize<WeatherForecast>(ref reader);

            // Place "after" code here (OnDeserialized)
            Console.WriteLine("OnDeserialized");

            return forecast;
        }

        public override void Write(
            Utf8JsonWriter writer,
            WeatherForecast forecast, JsonSerializerOptions options)
        {
            // Place "before" code here (OnSerializing)
            Console.WriteLine("OnSerializing");

            // Don't pass in options when recursively calling Serialize.
            JsonSerializer.Serialize(writer, forecast);

            // Place "after" code here (OnSerialized)
            Console.WriteLine("OnSerialized");
        }
    }
}

Registre esse conversor personalizado usando um atributo na classe ou adicionando o conversor à Converters coleção.Register this custom converter by using an attribute on the class or by adding the converter to the Converters collection.

Se você usar um conversor personalizado que segue o exemplo anterior:If you use a custom converter that follows the preceding sample:

  • O OnDeserializing código não tem acesso à nova instância poco.The OnDeserializing code doesn't have access to the new POCO instance. Para manipular a nova instância POCO no início da desserialização, coloque esse código no Construtor POCO.To manipulate the new POCO instance at the start of deserialization, put that code in the POCO constructor.
  • Não passe o objeto Options ao chamar de forma recursiva Serialize ou Deserialize .Don't pass in the options object when recursively calling Serialize or Deserialize. O objeto Options contém a Converters coleção.The options object contains the Converters collection. Se você passá-lo para Serialize ou Deserialize , o conversor será usado, fazendo um loop infinito que resulta em uma exceção de estouro de pilha.If you pass it in to Serialize or Deserialize, the converter will be used, making an infinite loop that results in a stack overflow exception.

Campos públicos e não públicosPublic and non-public fields

Newtonsoft.Jsonpode serializar e desserializar campos, bem como propriedades.Newtonsoft.Json can serialize and deserialize fields as well as properties. System.Text.Jsonfunciona apenas com propriedades públicas.System.Text.Json only works with public properties. Conversores personalizados podem fornecer essa funcionalidade.Custom converters can provide this functionality.

Setters e getters de propriedade interna e privadaInternal and private property setters and getters

Newtonsoft.Jsonpode usar setters e propriedades de propriedade privada e interna por meio do JsonProperty atributo.Newtonsoft.Json can use private and internal property setters and getters via the JsonProperty attribute. System.Text.Jsondá suporte apenas a setters públicos.System.Text.Json supports only public setters. Conversores personalizados podem fornecer essa funcionalidade.Custom converters can provide this functionality.

Popular objetos existentesPopulate existing objects

O JsonConvert.PopulateObject método em Newtonsoft.Json desserializa um documento JSON para uma instância existente de uma classe, em vez de criar uma nova instância.The JsonConvert.PopulateObject method in Newtonsoft.Json deserializes a JSON document to an existing instance of a class, instead of creating a new instance. System.Text.Jsonsempre cria uma nova instância do tipo de destino usando o construtor público sem parâmetros padrão.System.Text.Json always creates a new instance of the target type by using the default public parameterless constructor. Conversores personalizados podem desserializar em uma instância existente.Custom converters can deserialize to an existing instance.

Reutilização em vez de substituir PropriedadesReuse rather than replace properties

A Newtonsoft.Json ObjectCreationHandling configuração permite especificar que os objetos nas propriedades devem ser reutilizados em vez de substituídos durante a desserialização.The Newtonsoft.Json ObjectCreationHandling setting lets you specify that objects in properties should be reused rather than replaced during deserialization. System.Text.Jsonsempre substitui objetos em Propriedades.System.Text.Json always replaces objects in properties. Conversores personalizados podem fornecer essa funcionalidade.Custom converters can provide this functionality.

Adicionar a coleções sem settersAdd to collections without setters

Durante a desserialização, Newtonsoft.Json o adiciona objetos a uma coleção, mesmo que a propriedade não tenha nenhum setter.During deserialization, Newtonsoft.Json adds objects to a collection even if the property has no setter. System.Text.Jsonignora as propriedades que não têm setters.System.Text.Json ignores properties that don't have setters. Conversores personalizados podem fornecer essa funcionalidade.Custom converters can provide this functionality.

Cenários para os quais o JsonSerializer atualmente não dá suporteScenarios that JsonSerializer currently doesn't support

Para os cenários a seguir, as soluções alternativas não são práticas ou possíveis.For the following scenarios, workarounds are not practical or possible. Se você depender desses Newtonsoft.Json recursos, a migração não será possível sem alterações significativas.If you rely on these Newtonsoft.Json features, migration will not be possible without significant changes.

Preservar referências de objeto e manipular loopsPreserve object references and handle loops

Por padrão, o Newtonsoft.Json serializa por valor.By default, Newtonsoft.Json serializes by value. Por exemplo, se um objeto contiver duas propriedades que contêm uma referência ao mesmo Person objeto, os valores das Person Propriedades desse objeto serão duplicados no JSON.For example, if an object contains two properties that contain a reference to the same Person object, the values of that Person object's properties are duplicated in the JSON.

Newtonsoft.Jsontem uma PreserveReferencesHandling configuração no JsonSerializerSettings que permite serializar por referência:Newtonsoft.Json has a PreserveReferencesHandling setting on JsonSerializerSettings that lets you serialize by reference:

  • Um identificador de metadados é adicionado ao JSON criado para o primeiro Person objeto.An identifier metadata is added to the JSON created for the first Person object.
  • O JSON que é criado para o segundo Person objeto contém uma referência a esse identificador em vez de valores de propriedade.The JSON that is created for the second Person object contains a reference to that identifier instead of property values.

Newtonsoft.Jsontambém tem uma ReferenceLoopHandling configuração que permite ignorar referências circulares em vez de gerar uma exceção.Newtonsoft.Json also has a ReferenceLoopHandling setting that lets you ignore circular references rather than throw an exception.

System.Text.Jsondá suporte apenas à serialização por valor e gera uma exceção para referências circulares.System.Text.Json only supports serialization by value and throws an exception for circular references.

Atributos System. Runtime. SerializationSystem.Runtime.Serialization attributes

System.Text.JsonNão dá suporte a atributos do System.Runtime.Serialization namespace, como DataMemberAttribute e IgnoreDataMemberAttribute .System.Text.Json doesn't support attributes from the System.Runtime.Serialization namespace, such as DataMemberAttribute and IgnoreDataMemberAttribute.

Números octaisOctal numbers

Newtonsoft.JsonTrata os números com um zero à esquerda como números octais.Newtonsoft.Json treats numbers with a leading zero as octal numbers. System.Text.JsonNão permite zeros à esquerda porque a especificação RFC 8259 não permite.System.Text.Json doesn't allow leading zeroes because the RFC 8259 specification doesn't allow them.

MissingMemberHandlingMissingMemberHandling

Newtonsoft.Jsonpode ser configurado para gerar exceções durante a desserialização se o JSON incluir propriedades que estão ausentes no tipo de destino.Newtonsoft.Json can be configured to throw exceptions during deserialization if the JSON includes properties that are missing in the target type. System.Text.Jsonignora propriedades extras no JSON, exceto quando você usa o atributo [JsonExtensionData].System.Text.Json ignores extra properties in the JSON, except when you use the [JsonExtensionData] attribute. Não há nenhuma solução alternativa para o recurso de membro ausente.There's no workaround for the missing member feature.

TraceWriterTraceWriter

Newtonsoft.Jsonpermite que você depure usando um TraceWriter para exibir logs gerados pela serialização ou desserialização.Newtonsoft.Json lets you debug by using a TraceWriter to view logs that are generated by serialization or deserialization. System.Text.JsonNão faz registro em log.System.Text.Json doesn't do logging.

JsonDocument e Jsonelement em comparação com JToken (como JObject, JArray)JsonDocument and JsonElement compared to JToken (like JObject, JArray)

System.Text.Json.JsonDocumentfornece a capacidade de analisar e criar um Modelo de Objeto do Documento somente leitura (dom) de cargas JSON existentes.System.Text.Json.JsonDocument provides the ability to parse and build a read-only Document Object Model (DOM) from existing JSON payloads. 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 APIs para converter texto JSON em tipos .net comuns.The JsonElement type provides APIs to convert JSON text to common .NET types. JsonDocumentexpõe uma RootElement propriedade.JsonDocument exposes a RootElement property.

JsonDocument é IDisposableJsonDocument is IDisposable

JsonDocumentCria uma exibição na memória dos dados em um buffer em pool.JsonDocument builds an in-memory view of the data into a pooled buffer. Portanto, ao JObject contrário JArray de ou de Newtonsoft.Json , o JsonDocument tipo implementa IDisposable e precisa ser usado dentro de um bloco Using.Therefore, unlike JObject or JArray from Newtonsoft.Json, the JsonDocument type implements IDisposable and needs to be used inside a using block.

Retorne apenas uma JsonDocument da sua API se você quiser transferir a propriedade de tempo de vida e descartar a responsabilidade para o chamador.Only return a JsonDocument from your API if you want to transfer lifetime ownership and dispose responsibility to the caller. Na maioria dos cenários, isso não é necessário.In most scenarios, that isn't necessary. Se o chamador precisar trabalhar com o documento JSON inteiro, retorne o Clone do RootElement , que é um JsonElement .If the caller needs to work with the entire JSON document, return the Clone of the RootElement, which is a JsonElement. Se o chamador precisar trabalhar com um elemento específico dentro do documento JSON, retorne o Clone JsonElement .If the caller needs to work with a particular element within the JSON document, return the Clone of that JsonElement. Se você retornar o RootElement ou um subelemento diretamente sem fazer um Clone , o chamador não poderá acessar o retornado JsonElement depois JsonDocument que o proprietário for descartado.If you return the RootElement or a sub-element directly without making a Clone, the caller won't be able to access the returned JsonElement after the JsonDocument that owns it is disposed.

Aqui está um exemplo que exige que você faça um Clone :Here's an example that requires you to make a Clone:

public JsonElement LookAndLoad(JsonElement source)
{
    string json = File.ReadAllText(source.GetProperty("fileName").GetString());

    using (JsonDocument doc = JsonDocument.Parse(json))
    {
        return doc.RootElement.Clone();
    }
}

O código anterior espera um JsonElement que contém uma fileName propriedade.The preceding code expects a JsonElement that contains a fileName property. Ele abre o arquivo JSON e cria um JsonDocument .It opens the JSON file and creates a JsonDocument. O método pressupõe que o chamador deseja trabalhar com o documento inteiro e, portanto, retorna o Clone do RootElement .The method assumes that the caller wants to work with the entire document, so it returns the Clone of the RootElement.

Se você receber um JsonElement e estiver retornando um subelemento, não será necessário retornar um Clone do subelemento.If you receive a JsonElement and are returning a sub-element, it's not necessary to return a Clone of the sub-element. O chamador é responsável por manter a vida o JsonDocument que o passado JsonElement pertence.The caller is responsible for keeping alive the JsonDocument that the passed-in JsonElement belongs to. Por exemplo:For example:

public JsonElement ReturnFileName(JsonElement source)
{
   return source.GetProperty("fileName");
}

JsonDocument é somente leituraJsonDocument is read-only

O System.Text.Json dom não pode adicionar, remover ou modificar elementos JSON.The System.Text.Json DOM can't add, remove, or modify JSON elements. Ele foi projetado dessa forma para o desempenho e para reduzir as alocações para a análise de tamanhos de carga JSON comuns (ou seja, < 1 MB).It's designed this way for performance and to reduce allocations for parsing common JSON payload sizes (that is, < 1 MB). Se seu cenário usa atualmente um DOM modificável, uma das seguintes soluções alternativas pode ser viável:If your scenario currently uses a modifiable DOM, one of the following workarounds might be feasible:

  • Para criar um JsonDocument do zero (ou seja, sem passar um conteúdo JSON existente para o Parse método), grave o texto JSON usando o Utf8JsonWriter e analise a saída de para criar um novo JsonDocument .To build a JsonDocument from scratch (that is, without passing in an existing JSON payload to the Parse method), write the JSON text by using the Utf8JsonWriter and parse the output from that to make a new JsonDocument.
  • Para modificar um existente JsonDocument , use-o para gravar texto JSON, fazer alterações enquanto você escreve e analisar a saída do para criar um novo JsonDocument .To modify an existing JsonDocument, use it to write JSON text, making changes while you write, and parse the output from that to make a new JsonDocument.
  • Para mesclar documentos JSON existentes, equivalentes JObject.Merge às JContainer.Merge APIs ou do Newtonsoft.Json , consulte este problema do GitHub.To merge existing JSON documents, equivalent to the JObject.Merge or JContainer.Merge APIs from Newtonsoft.Json, see this GitHub issue.

Jsonelement é uma struct UnionJsonElement is a union struct

JsonDocumentexpõe o RootElement como uma propriedade do tipo JsonElement , que é um tipo Union, struct que abrange qualquer elemento JSON.JsonDocument exposes the RootElement as a property of type JsonElement, which is a union, struct type that encompasses any JSON element. Newtonsoft.Jsonusa tipos hierárquicos dedicados como JObject , JArray , JToken e assim por diante.Newtonsoft.Json uses dedicated hierarchical types like JObject,JArray, JToken, and so forth. JsonElementé o que você pode pesquisar e enumerar e pode usar JsonElement para materializar elementos JSON em tipos .net.JsonElement is what you can search and enumerate over, and you can use JsonElement to materialize JSON elements into .NET types.

Como pesquisar um JsonDocument e um Jsonelement para subelementosHow to search a JsonDocument and JsonElement for sub-elements

Procura tokens JSON usando JObject ou JArray de Newtonsoft.Json tendem a ser relativamente rápidos, pois são pesquisas em algum dicionário.Searches for JSON tokens using JObject or JArray from Newtonsoft.Json tend to be relatively fast because they're lookups in some dictionary. Por comparação, as pesquisas em JsonElement exigem uma pesquisa sequencial das propriedades e, portanto, são relativamente lentas (por exemplo, ao usar TryGetProperty ).By comparison, searches on JsonElement require a sequential search of the properties and hence is relatively slow (for example when using TryGetProperty). System.Text.Jsonfoi projetado para minimizar o tempo de análise inicial em vez da hora de pesquisa.System.Text.Json is designed to minimize initial parse time rather than lookup time. Portanto, use as seguintes abordagens para otimizar o desempenho ao pesquisar por um JsonDocument objeto:Therefore, use the following approaches to optimize performance when searching through a JsonDocument object:

  • Use os enumeradores internos ( EnumerateArray e EnumerateObject ) em vez de fazer sua própria indexação ou loops.Use the built-in enumerators (EnumerateArray and EnumerateObject) rather than doing your own indexing or loops.
  • Não faça uma pesquisa seqüencial no todo JsonDocument por meio de cada propriedade usando RootElement .Don't do a sequential search on the whole JsonDocument through every property by using RootElement. Em vez disso, pesquise objetos JSON aninhados com base na estrutura conhecida dos dados JSON.Instead, search on nested JSON objects based on the known structure of the JSON data. Por exemplo, se você estiver procurando uma Grade propriedade em Student objetos, faça um loop pelos Student objetos e obtenha o valor de Grade para cada um, em vez de Pesquisar por todos os JsonElement objetos procurando por Grade Propriedades.For example, if you're looking for a Grade property in Student objects, loop through the Student objects and get the value of Grade for each, rather than searching through all JsonElement objects looking for Grade properties. Fazer o último resultará em passagens desnecessárias nos mesmos dados.Doing the latter will result in unnecessary passes over the same data.

Para obter um exemplo de código, consulte usar JsonDocument para acessar dados.For a code example, see Use JsonDocument for access to data.

Utf8JsonReader em comparação com JsonTextReaderUtf8JsonReader compared to JsonTextReader

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.

As seções a seguir explicam os padrões de programação recomendados para o uso do Utf8JsonReader .The following sections explain recommended programming patterns for using Utf8JsonReader.

Utf8JsonReader é um struct de referênciaUtf8JsonReader is a ref struct

Como o Utf8JsonReader tipo é uma struct de referência, ele tem determinadas limitações.Because the Utf8JsonReader type is a ref struct, it has certain limitations. Por exemplo, ele não pode ser armazenado como um campo em uma classe ou struct diferente de um struct de referência.For example, it can't be stored as a field on a class or struct other than a ref struct. Para obter alto desempenho, esse tipo deve ser um, uma ref struct vez que ele precisa armazenar em cache a entrada ReadOnlySpan <byte> , que é um struct de referência.To achieve high performance, this type must be a ref struct since it needs to cache the input ReadOnlySpan<byte>, which itself is a ref struct. Além disso, esse tipo é mutável, pois mantém o estado.In addition, this type is mutable since it holds state. Portanto, passe-o por ref em vez de por valor.Therefore, pass it by ref rather than by value. Passá-lo por valor resultaria em uma cópia de struct e as alterações de estado não seriam visíveis para o chamador.Passing it by value would result in a struct copy and the state changes would not be visible to the caller. Isso Newtonsoft.Json é diferente desde que o Newtonsoft.Json JsonTextReader é uma classe.This differs from Newtonsoft.Json since the Newtonsoft.Json JsonTextReader is a class. Para obter mais informações sobre como usar structs de referência, consulte escrever código C# seguro e eficiente.For more information about how to use ref structs, see Write safe and efficient C# code.

Ler texto UTF-8Read UTF-8 text

Para obter o melhor desempenho possível ao usar o Utf8JsonReader , leia as cargas JSON já codificadas como texto UTF-8, e não como cadeias de caracteres UTF-16.To achieve the best possible performance while using the Utf8JsonReader, read JSON payloads already encoded as UTF-8 text rather than as UTF-16 strings. Para obter um exemplo de código, consulte filtrar dados usando Utf8JsonReader.For a code example, see Filter data using Utf8JsonReader.

Ler com um fluxo ou PipeReaderRead with a Stream or PipeReader

O Utf8JsonReader oferece suporte à leitura de um <byte> READONLYSPAN codificado em UTF-8 ou ReadOnlySequence <byte> (que é o resultado da leitura de um PipeReader ).The Utf8JsonReader supports reading from a UTF-8 encoded ReadOnlySpan<byte> or ReadOnlySequence<byte> (which is the result of reading from a PipeReader).

Para leitura síncrona, você pode ler a carga JSON até o final do fluxo em uma matriz de bytes e passá-la para o leitor.For synchronous reading, you could read the JSON payload until the end of the stream into a byte array and pass that into the reader. Para ler de uma cadeia de caracteres (que é codificada como UTF-16), chame UTF8 .GetBytesFor reading from a string (which is encoded as UTF-16), call UTF8.GetBytes para primeiro transcodificar a cadeia de caracteres em uma matriz de bytes codificada em UTF-8.to first transcode the string to a UTF-8 encoded byte array. Em seguida, passe-o para o Utf8JsonReader .Then pass that to the Utf8JsonReader.

Como o Utf8JsonReader considera a entrada como texto JSON, uma bom (marca de ordem de byte) UTF-8 é considerada JSON inválido.Since the Utf8JsonReader considers the input to be JSON text, a UTF-8 byte order mark (BOM) is considered invalid JSON. O chamador precisa filtrar isso antes de passar os dados para o leitor.The caller needs to filter that out before passing the data to the reader.

Para obter exemplos de código, consulte usar Utf8JsonReader.For code examples, see Use Utf8JsonReader.

Ler com ReadOnlySequence de vários segmentosRead with multi-segment ReadOnlySequence

Se a entrada JSON for um ReadOnlySpan <byte> , cada elemento JSON poderá ser acessado da ValueSpan propriedade no leitor à medida que você passar pelo loop de leitura.If your JSON input is a ReadOnlySpan<byte>, each JSON element can be accessed from the ValueSpan property on the reader as you go through the read loop. No entanto, se sua entrada for um <byte> ReadOnlySequence (que é o resultado da leitura de um PipeReader ), alguns elementos JSON poderão se ampliar de vários segmentos do ReadOnlySequence<byte> objeto.However, if your input is a ReadOnlySequence<byte> (which is the result of reading from a PipeReader), some JSON elements might straddle multiple segments of the ReadOnlySequence<byte> object. Esses elementos não podem ser acessados ValueSpan em um bloco de memória contíguo.These elements would not be accessible from ValueSpan in a contiguous memory block. Em vez disso, sempre que você tiver um multithread ReadOnlySequence<byte> como entrada, pesquise a HasValueSequence propriedade no leitor para descobrir como acessar o elemento JSON atual.Instead, whenever you have a multi-segment ReadOnlySequence<byte> as input, poll the HasValueSequence property on the reader to figure out how to access the current JSON element. Aqui está um padrão recomendado:Here's a recommended pattern:

while (reader.Read())
{
    switch (reader.TokenType)
    {
        // ...
        ReadOnlySpan<byte> jsonElement = reader.HasValueSequence ?
            reader.ValueSequence.ToArray() :
            reader.ValueSpan;
        // ...
    }
}

Usar ValueTextEquals para pesquisas de nome de propriedadeUse ValueTextEquals for property name lookups

Não use para fazer comparações de ValueSpan byte por byte chamando SequenceEqual pesquisas de nome de propriedade.Don't use ValueSpan to do byte-by-byte comparisons by calling SequenceEqual for property name lookups. Chame ValueTextEquals em vez disso, porque esse método desescapa quaisquer caracteres que tenham escape no JSON.Call ValueTextEquals instead, because that method unescapes any characters that are escaped in the JSON. Aqui está um exemplo que mostra como procurar uma propriedade denominada "Name":Here's an example that shows how to search for a property that is named "name":

private static readonly byte[] s_nameUtf8 = Encoding.UTF8.GetBytes("name");
while (reader.Read())
{
    JsonTokenType tokenType = reader.TokenType;

    switch (tokenType)
    {
        case JsonTokenType.StartObject:
            total++;
            break;
        case JsonTokenType.PropertyName:
            if (reader.ValueTextEquals(s_nameUtf8))
            {
                count++;
            }
            break;
    }

Ler valores nulos em tipos de valores anuláveisRead null values into nullable value types

Newtonsoft.Jsonfornece APIs que retornam Nullable<T> , como ReadAsBoolean , que lidam com a Null TokenType para você retornando um bool? .Newtonsoft.Json provides APIs that return Nullable<T>, such as ReadAsBoolean, which handles a Null TokenType for you by returning a bool?. As System.Text.Json APIs internas retornam apenas tipos de valores não anuláveis.The built-in System.Text.Json APIs return only non-nullable value types. Por exemplo, Utf8JsonReader.GetBoolean retorna um bool .For example, Utf8JsonReader.GetBoolean returns a bool. Ele lançará uma exceção se encontrar Null no JSON.It throws an exception if it finds Null in the JSON. Os exemplos a seguir mostram duas maneiras de lidar com nulos, um retornando um tipo de valor anulável e um retornando o valor padrão:The following examples show two ways to handle nulls, one by returning a nullable value type and one by returning the default value:

public bool? ReadAsNullableBoolean()
{
    _reader.Read();
    if (_reader.TokenType == JsonTokenType.Null)
    {
        return null;
    }
    if (_reader.TokenType != JsonTokenType.True && _reader.TokenType != JsonTokenType.False)
    {
        throw new JsonException();
    }
    return _reader.GetBoolean();
}
public bool ReadAsBoolean(bool defaultValue)
{
    _reader.Read();
    if (_reader.TokenType == JsonTokenType.Null)
    {
        return defaultValue;
    }
    if (_reader.TokenType != JsonTokenType.True && _reader.TokenType != JsonTokenType.False)
    {
        throw new JsonException();
    }
    return _reader.GetBoolean();
}

MultiplataformaMulti-targeting

Se você precisar continuar a usar Newtonsoft.Json para determinadas estruturas de destino, você pode ter vários destinos e ter duas implementações.If you need to continue to use Newtonsoft.Json for certain target frameworks, you can multi-target and have two implementations. No entanto, isso não é trivial e exigiria uma #ifdefs duplicação de origem.However, this is not trivial and would require some #ifdefs and source duplication. Uma maneira de compartilhar o máximo de código possível é criar um ref struct wrapper em volta de Utf8JsonReader e Newtonsoft.Json JsonTextReader .One way to share as much code as possible is to create a ref struct wrapper around Utf8JsonReader and Newtonsoft.Json JsonTextReader. Esse wrapper unificaria a área de superfície pública ao isolar as diferenças comportamentais.This wrapper would unify the public surface area while isolating the behavioral differences. Isso permite isolar as alterações principalmente na construção do tipo, juntamente com a passagem do novo tipo por referência.This lets you isolate the changes mainly to the construction of the type, along with passing the new type around by reference. Esse é o padrão que a biblioteca Microsoft. Extensions. DependencyModel segue:This is the pattern that the Microsoft.Extensions.DependencyModel library follows:

Utf8JsonWriter em comparação com JsonTextWriterUtf8JsonWriter compared to JsonTextWriter

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.

As seções a seguir explicam os padrões de programação recomendados para o uso do Utf8JsonWriter .The following sections explain recommended programming patterns for using Utf8JsonWriter.

Gravar com texto UTF-8Write with UTF-8 text

Para obter o melhor desempenho possível ao usar o Utf8JsonWriter , grave as cargas JSON já codificadas como texto UTF-8, e não como cadeias de caracteres UTF-16.To achieve the best possible performance while using the Utf8JsonWriter, write JSON payloads already encoded as UTF-8 text rather than as UTF-16 strings. Use JsonEncodedText para armazenar em cache e codificar previamente nomes de propriedade de cadeia de caracteres e valores como estáticos e passá-los para o gravador, em vez de usar literais de cadeia de caracteres UTF-16.Use JsonEncodedText to cache and pre-encode known string property names and values as statics, and pass those to the writer, rather than using UTF-16 string literals. Isso é mais rápido do que armazenar em cache e usar matrizes de bytes UTF-8.This is faster than caching and using UTF-8 byte arrays.

Essa abordagem também funcionará se você precisar fazer escapes personalizados.This approach also works if you need to do custom escaping. System.Text.JsonNão permite desabilitar o escape durante a gravação de uma cadeia de caracteres.System.Text.Json doesn't let you disable escaping while writing a string. No entanto, você pode passar seu próprio personalizado JavaScriptEncoder como uma opção para o gravador, ou criar seu próprio JsonEncodedText que usa o JavascriptEncoder para fazer a saída e, em seguida, escrever o JsonEncodedText em vez da cadeia de caracteres.However, you could pass in your own custom JavaScriptEncoder as an option to the writer, or create your own JsonEncodedText that uses your JavascriptEncoder to do the escaping, and then write the JsonEncodedText instead of the string. Para obter mais informações, consulte Personalizar codificação de caracteres.For more information, see Customize character encoding.

Gravar valores brutosWrite raw values

O Newtonsoft.Json WriteRawValue método grava JSON bruto onde um valor é esperado.The Newtonsoft.Json WriteRawValue method writes raw JSON where a value is expected. System.Text.JsonNão tem equivalente direto, mas aqui está uma solução alternativa que garante que apenas JSON válido seja gravado:System.Text.Json has no direct equivalent, but here's a workaround that ensures only valid JSON is written:

using JsonDocument doc = JsonDocument.Parse(string);
doc.WriteTo(writer);

Personalizar a saída de caracteresCustomize character escaping

A configuração StringEscapeHandling de JsonTextWriter oferece opções para escapar de todos os caracteres não ASCII ou caracteres HTML.The StringEscapeHandling setting of JsonTextWriter offers options to escape all non-ASCII characters or HTML characters. Por padrão, o Utf8JsonWriter escapa todos os caracteres não ASCII e HTML.By default, Utf8JsonWriter escapes all non-ASCII and HTML characters. Essa saída é feita para motivos de segurança de defesa intensa.This escaping is done for defense-in-depth security reasons. Para especificar uma política de saída diferente, crie um JavaScriptEncoder e defina JsonWriterOptions.Encoder .To specify a different escaping policy, create a JavaScriptEncoder and set JsonWriterOptions.Encoder. Para obter mais informações, consulte Personalizar codificação de caracteres.For more information, see Customize character encoding.

Personalizar o formato JSONCustomize JSON format

JsonTextWriterinclui as seguintes configurações, para as quais Utf8JsonWriter não tem equivalente:JsonTextWriter includes the following settings, for which Utf8JsonWriter has no equivalent:

  • Recuo – especifica o número de caracteres a serem recuados.Indentation - Specifies how many characters to indent. Utf8JsonWritersempre faz recuo de 2 caracteres.Utf8JsonWriter always does 2-character indentation.
  • IndentChar -especifica o caractere a ser usado para recuo.IndentChar - Specifies the character to use for indentation. Utf8JsonWritersempre usa espaço em branco.Utf8JsonWriter always uses whitespace.
  • QuoteChar -especifica o caractere a ser usado para envolver valores de cadeia de caracteres.QuoteChar - Specifies the character to use to surround string values. Utf8JsonWritersempre usa aspas duplas.Utf8JsonWriter always uses double quotes.
  • QUOTENAME – especifica se os nomes de propriedade devem ser circundados com aspas.QuoteName - Specifies whether or not to surround property names with quotes. Utf8JsonWritersempre circunda-os com aspas.Utf8JsonWriter always surrounds them with quotes.

Não há soluções alternativas que permitam personalizar o JSON produzido por Utf8JsonWriter essas maneiras.There are no workarounds that would let you customize the JSON produced by Utf8JsonWriter in these ways.

Gravar valores nulosWrite null values

Para gravar valores nulos usando Utf8JsonWriter , chame:To write null values by using Utf8JsonWriter, call:

  • WriteNullpara gravar um par chave-valor com NULL como o valor.WriteNull to write a key-value pair with null as the value.
  • WriteNullValuepara gravar NULL como um elemento de uma matriz JSON.WriteNullValue to write null as an element of a JSON array.

Para uma propriedade de cadeia de caracteres, se a cadeia de caracteres for nula e WriteString WriteStringValue for equivalente a WriteNull e WriteNullValue .For a string property, if the string is null, WriteString and WriteStringValue are equivalent to WriteNull and WriteNullValue.

Gravar valores de TimeSpan, URI ou CharWrite Timespan, Uri, or char values

JsonTextWriterfornece WriteValue métodos para valores de TimeSpan, URIe Char .JsonTextWriter provides WriteValue methods for TimeSpan, Uri, and char values. Utf8JsonWriterNão tem métodos equivalentes.Utf8JsonWriter doesn't have equivalent methods. Em vez disso, formate esses valores como cadeias de caracteres (chamando ToString() , por exemplo) e chame WriteStringValue .Instead, format these values as strings (by calling ToString(), for example) and call WriteStringValue.

MultiplataformaMulti-targeting

Se você precisar continuar a usar Newtonsoft.Json para determinadas estruturas de destino, você pode ter vários destinos e ter duas implementações.If you need to continue to use Newtonsoft.Json for certain target frameworks, you can multi-target and have two implementations. No entanto, isso não é trivial e exigiria uma #ifdefs duplicação de origem.However, this is not trivial and would require some #ifdefs and source duplication. Uma maneira de compartilhar o máximo de código possível é criar um wrapper em volta de Utf8JsonWriter e Newtonsoft JsonTextWriter .One way to share as much code as possible is to create a wrapper around Utf8JsonWriter and Newtonsoft JsonTextWriter. Esse wrapper unificaria a área de superfície pública ao isolar as diferenças comportamentais.This wrapper would unify the public surface area while isolating the behavioral differences. Isso permite isolar as alterações principalmente na construção do tipo.This lets you isolate the changes mainly to the construction of the type. A biblioteca Microsoft. Extensions. DependencyModel segue:Microsoft.Extensions.DependencyModel library follows:

Recursos adicionaisAdditional resources