Udostępnij przez


Klasa XmlSerializer nie ignoruje już właściwości oznaczonych przestarzałym atrybutem

Począwszy od .NET 10, zmieniło się zachowanie XmlSerializer w kontekście obsługi właściwości oznaczonych atrybutem ObsoleteAttribute. Wcześniej właściwości oznaczone elementem [Obsolete] były traktowane tak, jakby były również oznaczone znakiem [XmlIgnore], co spowodowało wykluczenie ich z serializacji XML. To zachowanie było niezamierzone i zostało poprawione.

W tej zmianie właściwości oznaczone przez [Obsolete] są teraz serializowane domyślnie, chyba że właściwość IsError jest ustawiona na true. Jeśli IsError jest true, serializator zgłasza InvalidOperationException podczas tworzenia. Ponadto wprowadzono przełącznik AppContext, Switch.System.Xml.IgnoreObsoleteMembers, aby umożliwić deweloperom przywrócenie poprzedniego zachowania w razie potrzeby.

Wersja wprowadzona

.NET 10

Poprzednie zachowanie

W poprzednich wersjach platformy .NET właściwości oznaczone atrybutem [Obsolete] były wykluczane z serializacji XML, podobnie jak właściwości oznaczone atrybutem [XmlIgnore]. To zachowanie było nieoczekiwane i nie było zgodne z zamierzonym celem atrybutu [Obsolete] , który polega na dostarczaniu ostrzeżeń dotyczących przestarzałych interfejsów API w czasie kompilacji.

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

Dane wyjściowe przed zmianą:

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

Nowe zachowanie

Począwszy od platformy .NET 10, właściwości oznaczone jako [Obsolete] nie są już domyślnie wykluczone z serializacji XML. Zamiast:

  • [Obsolete] Jeśli atrybut jest stosowany z IsError = false (ustawieniem domyślnym), właściwość jest serializowana normalnie.
  • Jeśli atrybut [Obsolete] jest stosowany z IsError = true, XmlSerializer zgłasza InvalidOperationException podczas tworzenia serializatora.

Używając tego samego kodu, jak pokazano w poprzedniej sekcji zachowania, dane wyjściowe po zmianie to:

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

Jeśli [Obsolete(IsError = true)] jest zastosowany do właściwości, podczas tworzenia serializatora zgłaszany jest następujący wyjątek:

System.InvalidOperationException: Nie można serializować elementu członkowskiego "ObsoleteProperty", ponieważ jest on oznaczony elementem ObsoleteAttribute, a właściwość IsError jest ustawiona na wartość true.

Uwaga / Notatka

Właściwości oznaczone jako [Obsolete] zawsze zostały pomyślnie zdeserializowane, gdy dane znajdują się w kodzie XML. Chociaż ta zmiana umożliwia właściwościom [Obsolete] pełne przekształcenie z obiektu do XML i z powrotem do obiektu, nowe zachowanie wpływa jedynie na etap serializacji (od obiektu do XML) tej pełnej konwersji.

Typ zmiany przełamującej

Ta zmiana jest zmianą behawioralną.

Przyczyna zmiany

Poprzednie zachowanie traktowania [Obsolete] jako równoważnego [XmlIgnore] było niezamierzone i niezgodne z celem atrybutu [Obsolete] . Ta zmiana gwarantuje, że [Obsolete] jest używana wyłącznie do zamierzonego celu dostarczania ostrzeżeń w czasie kompilacji i nie ma wpływu na zachowanie serializacji środowiska uruchomieniowego. Wprowadzenie przełącznika AppContext umożliwia deweloperom wybranie starszego zachowania w razie potrzeby.

Przejrzyj bazę kodu pod kątem wszelkich zależności od poprzedniego zachowania, w którym [Obsolete] właściwości zostały wykluczone z serializacji XML. Jeśli to zachowanie jest nadal pożądane, włącz przełącznik Switch.System.Xml.IgnoreObsoleteMembers AppContext w następujący sposób:

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

Jeśli jakiekolwiek właściwości są oznaczone i [Obsolete(IsError = true)] są serializowane, zaktualizuj kod, aby usunąć [Obsolete] atrybut lub ustawić, IsError = false aby uniknąć wyjątków środowiska uruchomieniowego.

Interfejsy API, których dotyczy problem