Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
a818b31
Add breaking change documentation for XmlSerializer ObsoleteAttribute…
Copilot Oct 22, 2025
a5e2288
Fix CancellationToken parameter naming for CA2016 rule (#49041) (#49042)
kurnakovv Oct 22, 2025
d21564c
Add formatting for CA2247 example (#49088)
kurnakovv Oct 22, 2025
34a2b60
Add code example for CA2251 rule (#49091) (#49092)
kurnakovv Oct 22, 2025
f2a4706
Add code example for CA1720 rule (#48958) (#48959)
kurnakovv Oct 23, 2025
b5e0f13
Add code example for CA1725 rule (#48960) (#48961)
kurnakovv Oct 23, 2025
eeaf182
Add code example for CA1727 rule (#48962) (#48963)
kurnakovv Oct 23, 2025
ed27215
Add code example for CA1822 rule (#48964) (#48965)
kurnakovv Oct 23, 2025
eae69e4
Add code example for CA1823 rule (#48966) (#48967)
kurnakovv Oct 23, 2025
1da7b6d
Add code example for CA2008 rule (#49035) (#49036)
kurnakovv Oct 23, 2025
da9bebe
Add code example for CA2012 rule (#49037) (#49038)
kurnakovv Oct 23, 2025
225d23b
Add code example for CA2014 rule (#49039) (#49040)
kurnakovv Oct 23, 2025
0c6575d
Add code example for CA2201 rule (#49058) (#49059)
kurnakovv Oct 23, 2025
91439ea
Add code example for CA2207 rule (#49060) (#49061)
kurnakovv Oct 23, 2025
ad90c00
Add code example for CA2219 rule (#49062) (#49063)
kurnakovv Oct 23, 2025
8aef630
Add code example for CA2253 rule (#49089) (#49090)
kurnakovv Oct 23, 2025
a551402
Add code example for CA2257 rule (#49109) (#49110)
kurnakovv Oct 23, 2025
4b1fdf5
Add code example for CA2256 rule (#49105) (#49107)
kurnakovv Oct 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/core/compatibility/10.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ If you're migrating an app to .NET 10, the breaking changes listed here might af
| [NUGET_ENABLE_ENHANCED_HTTP_RETRY environment variable removed](sdk/10.0/nuget-enhanced-http-retry-removed.md) | Behavioral change | Preview 6 |
| [NuGet logs an error for invalid package IDs](sdk/10.0/nuget-packageid-validation.md) | Behavioral change | RC 1 |

## Serialization

| Title | Type of change | Introduced version |
|-------|-------------------|--------------------|
| [XmlSerializer no longer ignores properties marked with ObsoleteAttribute](serialization/10/xmlserializer-obsolete-properties.md) | Behavioral change | Preview 1 |

## Windows Forms

| Title | Type of change | Introduced version |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
title: "Breaking change: XmlSerializer no longer ignores properties marked with ObsoleteAttribute"
description: "Learn about the breaking change in .NET 10 where properties marked with ObsoleteAttribute are now serialized by XmlSerializer instead of being ignored."
ms.date: 10/21/2025
ai-usage: ai-assisted
ms.custom: https://github.com/dotnet/docs/issues/49054
---
# XmlSerializer no longer ignores properties marked with ObsoleteAttribute

Starting in .NET 10, the behavior of <xref:System.Xml.Serialization.XmlSerializer> has changed with respect to how it handles properties marked with the <xref:System.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 <xref:System.ObsoleteAttribute.IsError> property 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.

## 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.

```csharp
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:**

```xml
<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 with `IsError = false` (default), the property is serialized normally.
- If the `[Obsolete]` attribute is applied with `IsError = true`, the <xref:System.Xml.Serialization.XmlSerializer> throws an <xref:System.InvalidOperationException> during serializer creation.

Using the same code as shown in the previous behavior section, the output after the change is:

```xml
<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](../../categories.md#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:

```csharp
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.

## Affected APIs

- <xref:System.Xml.Serialization.XmlSerializer?displayProperty=fullName>
4 changes: 4 additions & 0 deletions docs/core/compatibility/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ items:
href: sdk/10.0/prune-packagereference-privateassets.md
- name: Version requirements for .NET 10 SDK
href: sdk/10.0/version-requirements.md
- name: Serialization
items:
- name: XmlSerializer no longer ignores properties marked with ObsoleteAttribute
href: serialization/10/xmlserializer-obsolete-properties.md
- name: Windows Forms
items:
- name: API obsoletions
Expand Down
6 changes: 6 additions & 0 deletions docs/fundamentals/code-analysis/quality-rules/ca1720.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ helpviewer_keywords:
- CA1720
author: gewarren
ms.author: gewarren
dev_langs:
- CSharp
---
# CA1720: Identifiers should not contain type names

Expand Down Expand Up @@ -91,6 +93,10 @@ Replace the data type identifier in the name of the parameter with either a term

Replace the language-specific data type identifier in the name of the member with a term that better describes its meaning, a language-independent equivalent, or a more generic term, such as 'value'.

## Example

:::code language="csharp" source="snippets/csharp/all-rules/ca1720.cs" id="snippet1":::

## When to suppress warnings

Occasional use of type-based parameter and member names might be appropriate. However, for new development, no known scenarios occur where you should suppress a warning from this rule. For libraries that have previously shipped, you might have to suppress a warning from this rule.
Expand Down
6 changes: 6 additions & 0 deletions docs/fundamentals/code-analysis/quality-rules/ca1725.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ helpviewer_keywords:
- ParameterNamesShouldMatchBaseDeclaration
author: gewarren
ms.author: gewarren
dev_langs:
- CSharp
---
# CA1725: Parameter names should match base declaration

Expand All @@ -35,6 +37,10 @@ Consistent naming of parameters in an override hierarchy increases the usability

To fix a violation of this rule, rename the parameter to match the base declaration. The fix is a breaking change for callers who specify the parameter name.

## Example

:::code language="csharp" source="snippets/csharp/all-rules/ca1725.cs" id="snippet1":::

## When to suppress warnings

Do not suppress a warning from this rule except for visible methods in libraries that have previously shipped.
Expand Down
6 changes: 6 additions & 0 deletions docs/fundamentals/code-analysis/quality-rules/ca1727.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ helpviewer_keywords:
- CA1727
- LoggerMessageDefineAnalyzer
author: Youssef1313
dev_langs:
- CSharp
---
# CA1727: Use PascalCase for named placeholders

Expand All @@ -32,6 +34,10 @@ A named placeholder used with <xref:Microsoft.Extensions.Logging.ILogger> should

Use PascalCase for named placeholders. For example, change `{firstName}` to `{FirstName}`.

## Example

:::code language="csharp" source="snippets/csharp/all-rules/ca1727.cs" id="snippet1":::

## When to suppress warnings

It is safe to suppress a warning from this rule.
Expand Down
6 changes: 6 additions & 0 deletions docs/fundamentals/code-analysis/quality-rules/ca1822.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ helpviewer_keywords:
- CA1822
author: gewarren
ms.author: gewarren
dev_langs:
- CSharp
---
# CA1822: Mark members as static

Expand All @@ -33,6 +35,10 @@ Members that do not access instance data or call instance methods can be marked

Mark the member as static (or Shared in Visual Basic) or use 'this'/'Me' in the method body, if appropriate.

## Example

:::code language="csharp" source="snippets/csharp/all-rules/ca1822.cs" id="snippet1":::

## When to suppress warnings

It is safe to suppress a warning from this rule for previously shipped code for which the fix would be a breaking change.
Expand Down
7 changes: 7 additions & 0 deletions docs/fundamentals/code-analysis/quality-rules/ca1823.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ helpviewer_keywords:
- CA1823
author: gewarren
ms.author: gewarren
dev_langs:
- CSharp
---
# CA1823: Avoid unused private fields

Expand All @@ -33,6 +35,10 @@ Private fields were detected that do not appear to be accessed in the assembly.

To fix a violation of this rule, remove the field or add code that uses it.

## Example

:::code language="csharp" source="snippets/csharp/all-rules/ca1823.cs" id="snippet1":::

## When to suppress warnings

It is safe to suppress a warning from this rule.
Expand Down Expand Up @@ -60,3 +66,4 @@ For more information, see [How to suppress code analysis warnings](../suppress-w

- [CA1812: Avoid uninstantiated internal classes](ca1812.md)
- [CA1801: Review unused parameters](ca1801.md)
- [Remove unread private member (IDE0052)](../style-rules/ide0052.md)
40 changes: 40 additions & 0 deletions docs/fundamentals/code-analysis/quality-rules/ca2008.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ helpviewer_keywords:
- CA2008
author: gewarren
ms.author: gewarren
dev_langs:
- CSharp
---
# CA2008: Do not create tasks without passing a TaskScheduler

Expand Down Expand Up @@ -42,6 +44,44 @@ For further information and detailed examples, see [New TaskCreationOptions and

To fix violations, call the method overload that takes a <xref:System.Threading.Tasks.TaskScheduler> and explicitly pass in <xref:System.Threading.Tasks.TaskScheduler.Default%2A> or <xref:System.Threading.Tasks.TaskScheduler.Current%2A> to make the intent clear.

## Example

```csharp
// This code violates the rule.
var badTask = Task.Factory.StartNew(
() =>
{
// ...
}
);
badTask.ContinueWith(
t =>
{
// ...
}
);

// This code satisfies the rule.
var goodTask = Task.Factory.StartNew(
() =>
{
// ...
},
CancellationToken.None,
TaskCreationOptions.None,
TaskScheduler.Default
);
goodTask.ContinueWith(
t =>
{
// ...
},
CancellationToken.None,
TaskContinuationOptions.None,
TaskScheduler.Default
);
```

## When to suppress warnings

This warning is intended primarily for libraries, where the code may be executed in arbitrary environments and where code shouldn't make assumptions about the environment or how the caller of the method may be invoking or waiting on it. It may be appropriate to suppress the warning for projects that represent application code rather than library code.
Expand Down
6 changes: 6 additions & 0 deletions docs/fundamentals/code-analysis/quality-rules/ca2012.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ helpviewer_keywords:
- "CA2012"
author: stephentoub
ms.author: stoub
dev_langs:
- CSharp
---
# CA2012: Use ValueTasks correctly

Expand Down Expand Up @@ -37,6 +39,10 @@ In general, ValueTasks should be directly awaited rather than discarded or store

For `ValueTask` objects returned from arbitrary member calls, the caller needs to assume that the `ValueTask` must be consumed (for example, awaited) once and only once. However, if the developer also controls the member being invoked and has complete knowledge of its implementation, the developer may know it's safe to suppress the warning, for example, if the return `ValueTask` always wraps a <xref:System.Threading.Tasks.Task> object.

## Example

:::code language="csharp" source="snippets/csharp/all-rules/ca2012.cs" id="snippet1":::

## Suppress a warning

If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.
Expand Down
6 changes: 6 additions & 0 deletions docs/fundamentals/code-analysis/quality-rules/ca2014.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ helpviewer_keywords:
- "CA2014"
author: stephentoub
ms.author: stoub
dev_langs:
- CSharp
---
# CA2014: Do not use stackalloc in loops

Expand All @@ -33,6 +35,10 @@ The C# `stackalloc` expression allocates memory from the current stack frame, an

Move the `stackalloc` expression outside of all loops in the method.

## Example

:::code language="csharp" source="snippets/csharp/all-rules/ca2014.cs" id="snippet1":::

## When to suppress warnings

It may be safe to suppress the warning when the containing loop or loops are invoked only a finite number of times, such that the overall amount of memory allocated across all `stackalloc` operations is known to be relatively small.
Expand Down
Loading
Loading