Partager via


XmlSerializer n’ignore plus les propriétés marquées avec ObsoleteAttribute

À compter de .NET 10, le comportement de XmlSerializer a changé concernant la gestion des propriétés marquées avec l’attribut ObsoleteAttribute. Auparavant, les propriétés marquées avec [Obsolete] ont été traitées comme si elles étaient également marquées avec [XmlIgnore], ce qui les empêchait d’être exclues de la sérialisation XML. Ce comportement était inattendu et a été corrigé.

Avec cette modification, les propriétés marquées avec [Obsolete] sont désormais sérialisées par défaut, sauf si la propriété IsError est définie sur true. Si IsError est true, le sérialiseur lève une InvalidOperationException pendant la création. En outre, un commutateur AppContext a Switch.System.Xml.IgnoreObsoleteMembersété introduit pour permettre aux développeurs de revenir au comportement précédent, si nécessaire.

Version introduite

.NET 10

Comportement précédent

Dans les versions précédentes de .NET, les propriétés marquées avec l’attribut ont été exclues de la [Obsolete] sérialisation XML, comme les propriétés marquées avec [XmlIgnore]. Ce comportement était inattendu et n’était pas aligné sur l’objectif prévu de l’attribut [Obsolete] , qui consiste à fournir des avertissements au moment de la compilation concernant les API déconseillées.

public class Example
{
    public string NormalProperty { get; set; } = "normal";

    [Obsolete("This property is deprecated")]
    public string ObsoleteProperty { get; set; } = "obsolete";

    [XmlIgnore]
    public string IgnoredProperty { get; set; } = "ignored";
}

var obj = new Example();
var serializer = new XmlSerializer(typeof(Example));
using var writer = new StringWriter();
serializer.Serialize(writer, obj);
Console.WriteLine(writer.ToString());

Sortie avant la modification :

<Example>
  <NormalProperty>normal</NormalProperty>
</Example>

Nouveau comportement

À compter de .NET 10, les propriétés marquées avec [Obsolete] ne sont plus exclues de la sérialisation XML par défaut. Au lieu de:

  • Si l’attribut [Obsolete] est appliqué avec IsError = false (par défaut), la propriété est sérialisée normalement.
  • Si l’attribut [Obsolete] est appliqué avec IsError = true, le XmlSerializer lève une exception lors de la création du sérialiseur.

À l’aide du même code que celui indiqué dans la section de comportement précédente, la sortie après la modification est :

<Example>
  <NormalProperty>normal</NormalProperty>
  <ObsoleteProperty>obsolete</ObsoleteProperty>
</Example>

Si [Obsolete(IsError = true)] est appliqué à une propriété, l'exception suivante est levée lors de la création du sérialiseur :

System.InvalidOperationException : Impossible de sérialiser le membre « ObsoleteProperty », car il est marqué avec ObsoleteAttribute et IsError a la valeur true.

Note

Les propriétés marquées comme [Obsolete] ayant toujours été désérialisées lorsque les données sont présentes dans le code XML. Bien que cette modification permette aux propriétés de [Obsolete] de faire un « aller-retour » entre l’objet et le format XML, le nouveau comportement n'affecte que la partie sérialisation (de l'objet vers XML) de ce processus « aller-retour ».

Type de changement cassant

Ce changement est un changement de comportement.

Raison de la modification

Le comportement précédent de traiter [Obsolete] comme équivalent à [XmlIgnore] était inattendu et incohérent avec l’objectif de l’attribut [Obsolete] . Cette modification garantit qu’elle [Obsolete] est utilisée uniquement dans le but prévu de fournir des avertissements au moment de la compilation et n’affecte pas le comportement de sérialisation du runtime. L’introduction du commutateur AppContext permet aux développeurs de choisir le comportement hérité si nécessaire.

Passez en revue votre codebase pour toute dépendance sur le comportement précédent où [Obsolete] les propriétés ont été exclues de la sérialisation XML. Si ce comportement est toujours souhaité, activez le commutateur Switch.System.Xml.IgnoreObsoleteMembers AppContext comme suit :

AppContext.SetSwitch("Switch.System.Xml.IgnoreObsoleteMembers", true);

Si certaines propriétés sont marquées avec [Obsolete(IsError = true)] et sont en cours de sérialisation, mettez à jour le code pour soit supprimer l’attribut [Obsolete], soit définir IsError = false afin d'éviter les exceptions lors de l'exécution.

API affectées