Compartilhar via


XmlSerializer não ignora mais as propriedades marcadas com ObsoleteAttribute

A partir do .NET 10, o comportamento de XmlSerializer mudou em relação a como lida com propriedades marcadas com o atributo ObsoleteAttribute. Anteriormente, as propriedades marcadas com [Obsolete] eram tratadas como se também estivessem marcadas com [XmlIgnore], o que fazia com que elas fossem excluídas da serialização XML. Esse comportamento não foi intencional e foi corrigido.

Com essa alteração, as propriedades marcadas com [Obsolete] agora são serializadas por padrão, a menos que a IsError propriedade seja definida como true. Se IsError é true, o serializador lança um InvalidOperationException durante a criação. Além disso, uma chave AppContext, Switch.System.Xml.IgnoreObsoleteMembers, foi introduzida para permitir que os desenvolvedores revertam para o comportamento anterior, se necessário.

Versão introduzida

.NET 10

Comportamento anterior

Nas versões anteriores do .NET, as propriedades marcadas com o [Obsolete] atributo foram excluídas da serialização XML, semelhante às propriedades marcadas com [XmlIgnore]. Esse comportamento foi inesperado e não alinhado com a finalidade pretendida do [Obsolete] atributo, que é fornecer avisos de tempo de compilação sobre APIs preteridas.

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

Saída antes da alteração:

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

Novo comportamento

A partir do .NET 10, as propriedades marcadas com [Obsolete] não são mais excluídas da serialização XML por padrão. Em vez disso:

  • Se o [Obsolete] atributo for aplicado com IsError = false (padrão), a propriedade será serializada normalmente.
  • Se o [Obsolete] atributo for aplicado com IsError = true, o XmlSerializer lançará um InvalidOperationException durante a criação do serializador.

Usando o mesmo código mostrado na seção de comportamento anterior, a saída após a alteração é:

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

Se [Obsolete(IsError = true)] for aplicado a uma propriedade, a seguinte exceção será gerada durante a criação do serializador:

System.InvalidOperationException: não é possível serializar o membro 'ObsoleteProperty' porque ele está marcado com ObsoleteAttribute e IsError está definido como true.

Observação

Propriedades marcadas como [Obsolete] sempre foram desserializadas com êxito quando os dados estão presentes no XML. Embora essa alteração permita que [Obsolete] propriedades para "ida e volta" de objeto para XML e de volta ao objeto, o novo comportamento afeta apenas a parte de serialização (objeto para XML) do "ciclo completo".

Tipo de mudança disruptiva

Essa alteração é uma mudança comportamental.

Motivo da alteração

O comportamento anterior do tratamento [Obsolete] como equivalente [XmlIgnore] era não intencional e inconsistente com a finalidade do [Obsolete] atributo. Essa alteração garante que [Obsolete] seja usada exclusivamente para a finalidade pretendida de fornecer avisos de tempo de compilação e não afete o comportamento de serialização de runtime. A introdução da opção AppContext permite que os desenvolvedores optem pelo comportamento herdado, se necessário.

Examine sua base de código quanto a qualquer dependência do comportamento anterior em que [Obsolete] as propriedades foram excluídas da serialização XML. Se esse comportamento ainda for desejado, habilite o switch do AppContext Switch.System.Xml.IgnoreObsoleteMembers da seguinte maneira:

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

Se alguma propriedade estiver marcada com [Obsolete(IsError = true)] e estiver sendo serializada, atualize o código para remover o [Obsolete] atributo ou definir IsError = false para evitar exceções de runtime.

APIs afetadas