Compartilhar via


O desserializador baseado em reflexão resolve metadados rapidamente

O serializador baseado em reflexão System.Text.Json usou anteriormente uma abordagem de carregamento lento para resolver metadados de propriedade. Essa abordagem possibilitou que os POCOs que continham tipos de propriedade sem suporte desserializassem com êxito, desde que o JSON subjacente não se associasse a nenhuma das propriedades sem suporte. (Isso ocorreu apesar de instâncias do mesmo tipo não terem sido serializadas.)

A partir do .NET 8, o serializador foi alterado para que todas as propriedades sejam resolvidas rapidamente na serialização e na desserialização. Essa alteração foi feita para adicionar melhor suporte para combinar vários resolvedores, o que requer a análise antecipada do grafo de tipo serializado. Um efeito colateral dessa alteração é que, se você dependesse do comportamento anterior, poderia começar a ver novos erros de desserialização de runtime.

Comportamento anterior

O código de desserialização a seguir foi bem-sucedido no .NET 7.

var result = JsonSerializer.Deserialize<MyPoco>("""{ "Value": 1 }"""); //, MyContext.Default.MyPoco);
Console.WriteLine(result.Value);

public class MyPoco
{
    public int Value { get; set; }

    public NestedValue Unsupported { get; set; }
}

public class NestedValue
{
    public ReadOnlySpan<byte> Span => Array.Empty<byte>();
}

Novo comportamento

A partir do .NET 8, o mesmo código da seção de comportamento anterior gera um erro em tempo de execução InvalidOperationException.

System.InvalidOperationException: o tipo “System.ReadOnlySpan`1[System.Byte]” da propriedade “Span” no tipo “NestedValue” é inválido para serialização ou desserialização porque é um tipo de ponteiro, é um struct de referência ou contém parâmetros genéricos que não foram substituídos por tipos específicos.

Esse erro é consistente com o erro que foi gerado em versões anteriores se você tentou serializar uma instância do mesmo tipo. Ele também é consistente com o gerador de código-fonte, que produz um erro em tempo de compilação.

Versão introduzida

.NET 8 versão prévia 4

Tipo de mudança disruptiva

Esta é uma alteração comportamental.

Motivo da alteração

Os novos requisitos relacionados ao suporte à serialização de caminho rápido em contextos combinados gerados por origem (consulte dotnet/runtime#71933).

Se essa alteração for problemática para você, você poderá:

  • Remover a propriedade sem suporte do seu tipo.

  • Crie um conversor personalizado para o tipo sem suporte.

  • Adicione o JsonIgnoreAttribute atributo:

    public class MyPoco
    {
        public int Value { get; set; }
    
        [JsonIgnore]
        public NestedValue Unsupported { get; set; }
    }
    

APIs afetadas