Partilhar via


O desserializador baseado em reflexão resolve metadados ansiosamente

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

A partir do .NET 8, o serializador foi alterado para que todas as propriedades sejam resolvidas ansiosamente na serialização e na desserialização. Essa alteração foi feita para adicionar um melhor suporte para a combinação de vários resolvedores, o que requer uma análise precoce do gráfico 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 em tempo de execução.

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 lança 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 ref struct ou contém parâmetros genéricos que não foram substituídos por tipos específicos.

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

Versão introduzida

.NET 8 Visualização 4

Tipo de mudança de rutura

Esta mudança é uma mudança comportamental.

Razão para a alteração

Essa alteração foi necessária devido aos novos requisitos relacionados ao suporte à serialização de caminho rápido em contextos gerados por fonte combinada (consulte dotnet/runtime#71933).

Se esta alteração for problemática para si, pode:

  • Remova a propriedade sem suporte do seu tipo.

  • Crie um conversor personalizado para o tipo não suportado.

  • Adicione o JsonIgnoreAttribute atributo:

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

APIs afetadas