Udostępnij za pośrednictwem


Konstruktor kopiujący JsonSerializerOptions uwzględnia JsonSerializerContext

Wraz z wydaniem generowania źródła w .NET 6, konstruktor kopiujący JsonSerializerOptions został celowo zaprojektowany tak, aby ignorować stan JsonSerializerContext. Miało to sens w tym czasie, ponieważ JsonSerializerContext zostało zaprojektowane tak, aby mieć relację 1:1 z JsonSerializerOptions instancjami. W programie .NET 7 IJsonTypeInfoResolver zastępuje JsonSerializerContext dla uogólnienia kontekstu, co eliminuje potrzebę ścisłego powiązania między elementami JsonSerializerOptions i JsonSerializerContext. Konstruktor kopiowania teraz zawiera IJsonTypeInfoResolver/JsonSerializerContext informację, co może manifestować się jako zmiana niezgodna w niektórych scenariuszach.

Poprzednie zachowanie

Na platformie .NET 6 następujący kod serializuje się pomyślnie. Konfiguracja MyContext (która nie obsługuje Poco2) jest odrzucana przez konstruktora kopiowania, a serializacja kończy się powodzeniem, ponieważ nowe wystąpienie opcji domyślnie używa serializacji opartej na odbiciu.

var options = new JsonSerializerOptions(MyContext.Default.Options);
JsonSerializer.Serialize(new Poco2(), options);

[JsonSerializable(typeof(Poco1))]
public partial class MyContext : JsonSerializerContext {}

public class Poco1 {}
public class Poco2 {}

Nowe zachowanie

Począwszy od platformy .NET 7, ten sam kod, jak pokazano w sekcji Poprzednie zachowanie , zgłasza błąd InvalidOperationException. Dzieje się tak, ponieważ konstruktor kopiowania zawiera teraz metadane MyContext , które nie obsługują Poco2 kontraktów.

Wersja wprowadzona

.NET 7

Typ zmiany przełamującej

Ta zmiana może mieć wpływ na zgodność binarną.

Przyczyna zmiany

JsonSerializerContext był jedynym ustawieniem ignorowanym przez konstruktor kopiujący. To zachowanie było zaskakujące dla niektórych użytkowników.

Jeśli polegasz na zachowaniu w wersji .NET 6, możesz ręcznie zresetować właściwość TypeInfoResolver, aby uzyskać rozwiązanie kontraktu opartego na odbiciu.

var options = new JsonSerializerOptions(MyContext.Default.Options);
options.TypeInfoResolver = null; // Unset `MyContext.Default` as the resolver for the options instance.

Interfejsy API, których dotyczy problem