Skip to content

Commit 36f6a86

Browse files
Copilotgewarren
andcommitted
Add breaking change doc for XmlSerializer ObsoleteAttribute behavior
Co-authored-by: gewarren <[email protected]>
1 parent 49632b3 commit 36f6a86

File tree

3 files changed

+133
-0
lines changed

3 files changed

+133
-0
lines changed

docs/core/compatibility/10.0.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ If you're migrating an app to .NET 10, the breaking changes listed here might af
130130
| [NUGET_ENABLE_ENHANCED_HTTP_RETRY environment variable removed](sdk/10.0/nuget-enhanced-http-retry-removed.md) | Behavioral change | Preview 6 |
131131
| [NuGet logs an error for invalid package IDs](sdk/10.0/nuget-packageid-validation.md) | Behavioral change | RC 1 |
132132

133+
## Serialization
134+
135+
| Title | Type of change | Introduced version |
136+
|-------|-------------------|--------------------|
137+
| [XmlSerializer no longer ignores properties marked with ObsoleteAttribute](serialization/10.0/xmlserializer-obsolete-properties.md) | Behavioral change | Preview 1 |
138+
133139
## Windows Forms
134140

135141
| Title | Type of change | Introduced version |
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
---
2+
title: "Breaking change: XmlSerializer no longer ignores properties marked with ObsoleteAttribute"
3+
description: "Learn about the breaking change in .NET 10 where properties marked with ObsoleteAttribute are now serialized by XmlSerializer instead of being ignored."
4+
ms.date: 10/21/2025
5+
ai-usage: ai-assisted
6+
ms.custom: https://github.com/dotnet/runtime/issues/100453
7+
---
8+
# XmlSerializer no longer ignores properties marked with ObsoleteAttribute
9+
10+
Starting in .NET 10, the behavior of <xref:System.Xml.Serialization.XmlSerializer> has changed with respect to how it handles properties marked with the `[Obsolete]` 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.
11+
12+
With this change, properties marked with `[Obsolete]` are now serialized by default unless the `IsError` property of the `[Obsolete]` attribute is set to `true`. If `IsError` is `true`, the serializer throws an <xref:System.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.
13+
14+
## Version introduced
15+
16+
.NET 10 Preview 1
17+
18+
## Previous behavior
19+
20+
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.
21+
22+
```csharp
23+
public class Example
24+
{
25+
public string NormalProperty { get; set; } = "normal";
26+
27+
[Obsolete("This property is deprecated")]
28+
public string ObsoleteProperty { get; set; } = "obsolete";
29+
30+
[XmlIgnore]
31+
public string IgnoredProperty { get; set; } = "ignored";
32+
}
33+
34+
var obj = new Example();
35+
var serializer = new XmlSerializer(typeof(Example));
36+
using var writer = new StringWriter();
37+
serializer.Serialize(writer, obj);
38+
Console.WriteLine(writer.ToString());
39+
```
40+
41+
**Output before the change:**
42+
43+
```xml
44+
<Example>
45+
<NormalProperty>normal</NormalProperty>
46+
</Example>
47+
```
48+
49+
## New behavior
50+
51+
Starting in .NET 10, properties marked with `[Obsolete]` are no longer excluded from XML serialization by default. Instead:
52+
53+
1. If the `[Obsolete]` attribute is applied with `IsError = false` (default), the property is serialized normally.
54+
2. If the `[Obsolete]` attribute is applied with `IsError = true`, the <xref:System.Xml.Serialization.XmlSerializer> throws an <xref:System.InvalidOperationException> during serializer creation.
55+
56+
An AppContext switch, `Switch.System.Xml.IgnoreObsoleteMembers`, has been introduced to allow developers to restore the previous behavior where `[Obsolete]` properties are ignored during serialization. This switch is off by default.
57+
58+
Using the same code as above, the output after the change is:
59+
60+
**Output after the change (default behavior):**
61+
62+
```xml
63+
<Example>
64+
<NormalProperty>normal</NormalProperty>
65+
<ObsoleteProperty>obsolete</ObsoleteProperty>
66+
</Example>
67+
```
68+
69+
If the AppContext switch `Switch.System.Xml.IgnoreObsoleteMembers` is enabled, the previous behavior is restored:
70+
71+
```csharp
72+
AppContext.SetSwitch("Switch.System.Xml.IgnoreObsoleteMembers", true);
73+
74+
var obj = new Example();
75+
var serializer = new XmlSerializer(typeof(Example));
76+
using var writer = new StringWriter();
77+
serializer.Serialize(writer, obj);
78+
Console.WriteLine(writer.ToString());
79+
```
80+
81+
**Output with AppContext switch enabled:**
82+
83+
```xml
84+
<Example>
85+
<NormalProperty>normal</NormalProperty>
86+
</Example>
87+
```
88+
89+
If `[Obsolete(IsError = true)]` is applied to a property, the following exception is thrown during serializer creation:
90+
91+
```
92+
System.InvalidOperationException: Cannot serialize member 'ObsoleteProperty' because it is marked with ObsoleteAttribute and IsError is set to true.
93+
```
94+
95+
> [!NOTE]
96+
> 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 only affects the serialization half (object to XML) of the "round trip."
97+
98+
## Type of breaking change
99+
100+
This change is a [behavioral change](../../categories.md#behavioral-change).
101+
102+
## Reason for change
103+
104+
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.
105+
106+
## Recommended action
107+
108+
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:
109+
110+
```csharp
111+
AppContext.SetSwitch("Switch.System.Xml.IgnoreObsoleteMembers", true);
112+
```
113+
114+
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.
115+
116+
## Affected APIs
117+
118+
- <xref:System.Xml.Serialization.XmlSerializer?displayProperty=fullName>
119+
120+
## See also
121+
122+
- [Pull Request dotnet/runtime#119865](https://github.com/dotnet/runtime/pull/119865)
123+
- [Related Issue dotnet/runtime#100453](https://github.com/dotnet/runtime/issues/100453)

docs/core/compatibility/toc.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ items:
162162
href: sdk/10.0/prune-packagereference-privateassets.md
163163
- name: Version requirements for .NET 10 SDK
164164
href: sdk/10.0/version-requirements.md
165+
- name: Serialization
166+
items:
167+
- name: XmlSerializer no longer ignores properties marked with ObsoleteAttribute
168+
href: serialization/10.0/xmlserializer-obsolete-properties.md
165169
- name: Windows Forms
166170
items:
167171
- name: API obsoletions

0 commit comments

Comments
 (0)