Compartir a través de


XmlSerializer ya no omite las propiedades marcadas con ObsoleteAttribute

A partir de .NET 10, el comportamiento de XmlSerializer ha cambiado con respecto a cómo controla las propiedades marcadas con el ObsoleteAttribute atributo . Anteriormente, las propiedades marcadas con [Obsolete] se trataron como si también estuvieran marcadas con [XmlIgnore], lo que hace que se excluyan de la serialización XML. Este comportamiento no se ha deseado y se ha corregido.

Con este cambio, las propiedades marcadas con [Obsolete] ahora se serializan por defecto, a menos que la propiedad IsError esté configurada en true. Si IsError es true, el serializador lanza una InvalidOperationException durante la creación. Además, se ha introducido un modificador AppContext, Switch.System.Xml.IgnoreObsoleteMembers, para permitir a los desarrolladores revertir al comportamiento anterior, si es necesario.

Versión introducida

.NET 10

Comportamiento anterior

En versiones anteriores de .NET, las propiedades marcadas con el atributo [Obsolete] se excluían de la serialización XML, similar a las propiedades marcadas con [XmlIgnore]. Este comportamiento fue inesperado y no se alineó con el propósito previsto del [Obsolete] atributo, que es proporcionar advertencias en tiempo de compilación sobre las API en desuso.

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());

Salida antes del cambio:

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

Nuevo comportamiento

A partir de .NET 10, las propiedades marcadas con [Obsolete] ya no se excluyen de la serialización XML de forma predeterminada. En lugar de:

  • Si el [Obsolete] atributo se aplica con IsError = false (valor predeterminado), la propiedad se serializa normalmente.
  • Si se aplica el atributo [Obsolete] con IsError = true, se lanza una excepción XmlSerializer durante la creación del serializador InvalidOperationException.

Con el mismo código que se muestra en la sección comportamiento anterior, la salida después del cambio es:

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

Si [Obsolete(IsError = true)] se aplica a una propiedad, se produce la siguiente excepción durante la creación del serializador:

System.InvalidOperationException: no se puede serializar el miembro 'ObsoleteProperty' porque está marcado con ObsoleteAttribute e IsError está establecido en true.

Nota:

Las propiedades marcadas como [Obsolete] siempre se han deserializado correctamente cuando los datos están presentes en el XML. Aunque este cambio permite que las propiedades de [Obsolete] realicen un "viaje de ida y vuelta" desde el objeto a XML y de vuelta al objeto, el nuevo comportamiento afecta solo a la mitad de la serialización (objeto a XML) del "viaje de ida y vuelta".

Tipo de cambio disruptivo

Este es un cambio de comportamiento.

Motivo del cambio

El comportamiento anterior de tratar [Obsolete] como equivalente a [XmlIgnore] no era deseado e incoherente con el propósito del [Obsolete] atributo. Este cambio garantiza que [Obsolete] se use únicamente para su propósito previsto de proporcionar advertencias en tiempo de compilación y no afecte al comportamiento de serialización en tiempo de ejecución. La introducción del conmutador AppContext permite a los desarrolladores optar por el comportamiento heredado si es necesario.

Revise el código base para cualquier dependencia del comportamiento anterior en el que [Obsolete] las propiedades se excluyeron de la serialización XML. Si este comportamiento sigue siendo deseado, habilite el modificador Switch.System.Xml.IgnoreObsoleteMembers AppContext de la siguiente manera:

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

Si se marcan propiedades con [Obsolete(IsError = true)] y se están serializando, actualice el código para quitar el [Obsolete] atributo o establecer IsError = false para evitar excepciones en tiempo de ejecución.

Las APIs afectadas