Dela via


Reflektionsbaserad deserializer löser metadata ivrigt

System.Text.Json-reflektionsbaserad serialiserare använde tidigare en lat inläsningsmetod för att lösa egenskapsmetadata. Den metoden gjorde det möjligt för POCO:er som innehöll egenskapstyper som inte stöds att deserialisera korrekt, förutsatt att den underliggande JSON inte binder till någon av de egenskaper som inte stöds. (Detta trots att instanser av samma typ inte kunde serialiseras.)

Från och med .NET 8 har serialiseraren ändrats så att alla egenskaper löses ivrigt i både serialisering och deserialisering. Den här ändringen gjordes för att ge bättre stöd för att kombinera flera matchare, vilket kräver tidig analys av den serialiserade typgrafen. En bieffekt av den här ändringen är att om du var beroende av det tidigare beteendet kan du börja se nya runtime-deserialiseringsfel.

Tidigare beteende

Följande deserialiseringskod lyckades i .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>();
}

Nytt beteende

Från och med .NET 8 genererar samma kod från avsnittet Föregående beteende en InvalidOperationException vid körning.

System.InvalidOperationException: Typen "System.ReadOnlySpan'1[System.Byte]" för egenskapen "Span" på typen "NestedValue" är ogiltig för serialisering eller deserialisering eftersom det är en pekartyp, är en referensstruct eller innehåller generiska parametrar som inte har ersatts av specifika typer.

Det här felet stämmer överens med det fel som utlöstes även i tidigare versioner om du försökte serialisera en instans av samma typ. Det är också konsekvent med källgeneratorn, som genererar ett kompileringsfel.

Version introducerad

Förhandsversion av .NET 8 4

Typ av icke-bakåtkompatibel ändring

Den här ändringen är en beteendeförändring.

Orsak till ändringen

Den här ändringen krävdes av nya krav relaterade till stöd för snabbsökvägs serialisering i kombinerade källgenererade kontexter (se dotnet/runtime#71933).

Om den här ändringen är problematisk kan du:

  • Ta bort egenskapen som inte stöds från din typ.

  • Skapa en anpassad konverterare för den typ som inte stöds.

  • Lägg till attributet JsonIgnoreAttribute :

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

Berörda API:er