.NET 6, A guide for the high impact Breaking Changes
.NET 6 is the first Long-Term-Support (LTS) version since the “one .NET to rule them all” era, which means it’s plan as future-proof. It includes a tone of improvements and changes that are planned to live long, thing that brought with it a few high impact Breaking Changes. Although there are lower impact braking changes too, this guide will help you identify if any of the important ones really affect you, and provide a suggestion at the same time.
.NET 6 is the fastest full stack web framework, which lowers compute costs if you’re running in the cloud, and with Visual Studio 2022 provides hot reload, new git tooling, intelligent code editing, robust diagnostics and testing tools, and better team collaboration. C# 10, while focused on microservices, was simplified by reducing the amount of code you need to write!
Source Code compatible changes
The following group of breaking changes require no change in your code and thus they are the easiest ones! The changes are grouped by technology area
Assemblies removedBreaking Change
The following assemblies were removed from
Please manually add the equivalent reference
Middleware: New Use overloadBreaking Change
A new overload of
app.Usehas been introduced. If you call
app.Usebut never call the next middleware, you’ll now get compiler error CS0121:
The call is ambiguous between the following methods or properties: 'UseExtensions.Use(IApplicationBuilder, Func<HttpContext, Func, Task>)' and 'UseExtensions.Use(IApplicationBuilder, Func<HttpContext, RequestDelegate, Task>)'
To resolve the error, use
MVC doesn’t buffer Breaking Change
IAsyncEnumerable types when using
When formatting using
System.Text.Json, MVC no longer buffers
If your application requires buffering, consider manually buffering the
IAsyncEnumerable<T>object by using, for example,
Core .NET libraries
Nullable reference type annotations changedBreaking Change
The affected APIs had incorrect nullable reference type annotations with build warnings being either absent or incorrect. New build warnings are produced and incorrect build warnings are no longer produced for those APIs. The following list contains the most common APIs that have a breaking change:
Methods that override Object.Equals(Object)
Update code that calls these APIs to reflect the revised nullability contracts.
API obsoletions with non-default diagnostic IDsBreaking Change
WebClientproduces an error with a custom diagnostic ID.
An even bigger list of APIs has become obsolete and produces warnings. For a full list of these APIs visit Microsoft Docs.
Older framework versions dropped from packageBreaking Change
Starting with .NET 6 Preview 5, the core libraries packages can no longer be installed into projects whose target framework is older than:
- .NET Framework 4.6.1
- .NET Core 3.1
- .NET Standard 2.0
Upgrade your project to a newer version of .NET
Unhandled exceptions from a Breaking Change
In previous versions, when a BackgroundService throws an unhandled exception, the exception is lost and the service appears unresponsive. .NET 6 fixes this behavior by logging the exception and stopping the host.
If you prefer to keep the previous behavior of allowing an unhandled exception in a
BackgroundServiceto not stop the Host, you can set
Asynchronous serialization methods now enumerate any
IAsyncEnumerable<T>instances in an object graph and then serialize them as JSON arrays. Synchronous serializations methods do not support
IAsyncEnumerable<T>serialization and throw a
Check if your serialization models contain types that implement
IAsyncEnumerable<T>and determine if emitting the enumeration in the JSON output is desirable. You can disable
IAsyncEnumerable<T>serialization in one of the following ways:
- Attach a
JsonIgnoreAttributeto the property containing the
- Define a custom converter factory that serializes
IAsyncEnumerable<T>instances as empty JSON objects.
EF Core 6
Nested optional dependents sharing a table and with no required properties are disallowedBreaking Change
Models with nested optional dependents sharing a table and with no required properties were allowed, but could result in data loss when querying for the data and then saving again. To prevent this, a new exception will be thrown
Avoid using optional dependents sharing a table and with no required properties. There are three easy ways to do this:
- Make the dependents required. This means that the dependent entity will always have a value after it is queried, even if all its properties are null.
- Make sure that the dependent contains at least one required property.
- Map optional dependents to their own table, instead of sharing a table with the principal.