Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Starting in .NET 10, the behavior of XmlSerializer has changed with respect to how it handles properties marked with the ObsoleteAttribute attribute. Previously, properties marked with [Obsolete] were treated as if they were also marked with [XmlIgnore], causing them to be excluded from XML serialization. This behavior was unintended and has been corrected.
With this change, properties marked with [Obsolete] are now serialized by default unless the IsError property is set to true. If IsError is true, the serializer throws an InvalidOperationException during creation. Additionally, an AppContext switch, Switch.System.Xml.IgnoreObsoleteMembers, has been introduced to allow developers to revert to the previous behavior, if necessary.
Version introduced
.NET 10 Preview 1
Previous behavior
In previous versions of .NET, properties marked with the [Obsolete] attribute were excluded from XML serialization, similar to properties marked with [XmlIgnore]. This behavior was unexpected and not aligned with the intended purpose of the [Obsolete] attribute, which is to provide compile-time warnings about deprecated APIs.
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());
Output before the change:
<Example>
<NormalProperty>normal</NormalProperty>
</Example>
New behavior
Starting in .NET 10, properties marked with [Obsolete] are no longer excluded from XML serialization by default. Instead:
- If the
[Obsolete]attribute is applied withIsError = false(default), the property is serialized normally. - If the
[Obsolete]attribute is applied withIsError = true, the XmlSerializer throws an InvalidOperationException during serializer creation.
Using the same code as shown in the previous behavior section, the output after the change is:
<Example>
<NormalProperty>normal</NormalProperty>
<ObsoleteProperty>obsolete</ObsoleteProperty>
</Example>
If [Obsolete(IsError = true)] is applied to a property, the following exception is thrown during serializer creation:
System.InvalidOperationException: Cannot serialize member 'ObsoleteProperty' because it is marked with ObsoleteAttribute and IsError is set to true.
Note
Properties that are marked as [Obsolete] have always successfully deserialized when data is present in the XML. While this change allows [Obsolete] properties to "round trip" from object to XML and back to object, the new behavior affects only the serialization half (object to XML) of the "round trip."
Type of breaking change
This change is a behavioral change.
Reason for change
The previous behavior of treating [Obsolete] as equivalent to [XmlIgnore] was unintended and inconsistent with the purpose of the [Obsolete] attribute. This change ensures that [Obsolete] is used solely for its intended purpose of providing compile-time warnings and doesn't affect runtime serialization behavior. The introduction of the AppContext switch allows developers to opt in to the legacy behavior if necessary.
Recommended action
Review your codebase for any reliance on the previous behavior where [Obsolete] properties were excluded from XML serialization. If this behavior is still desired, enable the AppContext switch Switch.System.Xml.IgnoreObsoleteMembers as follows:
AppContext.SetSwitch("Switch.System.Xml.IgnoreObsoleteMembers", true);
If any properties are marked with [Obsolete(IsError = true)] and are being serialized, update the code to either remove the [Obsolete] attribute or set IsError = false to avoid runtime exceptions.