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 POCOs que continham tipos de propriedades sem suporte fossem desserializados com êxito, desde que o JSON subjacente não estivesse associado 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 Comportamento anterior gera um InvalidOperationException em tempo de execução.

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 origem, que produz um erro em tempo de compilação.

Versão introduzida

.NET 8 versão prévia 4

Tipo de alteração interruptiva

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.

  • Criar um conversor personalizado para o tipo sem suporte.

  • Adicionar o atributo JsonIgnoreAttribute:

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

APIs afetadas