Le constructeur de copie JsonSerializerOptions inclut JsonSerializerContext

Avec la publication de la génération de sources dans .NET 6, le constructeur de copie JsonSerializerOptions a été intentionnellement conçu pour ignorer son état JsonSerializerContext. Cela était logique à l’époque, car JsonSerializerContext était conçu pour avoir une relation 1:1 avec les instances JsonSerializerOptions. Dans .NET 7, IJsonTypeInfoResolver remplace JsonSerializerContext pour généraliser le contexte, ce qui supprime la nécessité d’un couplage étroit entre JsonSerializerOptions et JsonSerializerContext. Le constructeur de copie inclut à présent les informations IJsonTypeInfoResolver/JsonSerializerContext, qui peuvent se manifester sous forme de changement cassant pour certains scénarios.

Comportement précédent

Dans .NET 6, le code suivant sérialise correctement. La configuration MyContext (qui ne prend pas en charge Poco2) est ignorée par le constructeur de copie et la sérialisation réussit, car la nouvelle instance d’options utilise par défaut la sérialisation basée sur la réflexion.

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 {}

Nouveau comportement

À partir de .NET 7, le même code que celui indiqué dans la section Comportement précédent lève un InvalidOperationException. En effet, le constructeur de copie incorpore à présent des métadonnées MyContext, qui ne prennent pas en charge les contrats Poco2.

Version introduite

.NET 7

Type de changement cassant

Ce changement peut affecter la compatibilité binaire.

Raison du changement

JsonSerializerContext était le seul paramètre ignoré par le constructeur de copie. Ce comportement était surprenant pour certains utilisateurs.

Si vous dépendez du comportement .NET 6, vous pouvez annuler manuellement la propriété TypeInfoResolver pour obtenir une résolution de contrat basée sur la réflexion :

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

API affectées