.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
ASP.NET Core
Assemblies removed
Breaking ChangeThe following assemblies were removed from
Microsoft.AspNetCore.App
shared framework: System.Security.Permissions
, System.Windows.Extensions
, Microsoft.Win32.SystemEvents
, System.Drawing.Common
, System.Security.Permissions
, System.Windows.Extensions
Solution
Please manually add the equivalent reference
Middleware: New Use overload
Breaking ChangeA new overload of
app.Use
has been introduced. If you call app.Use
but 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>)'
Solution
To resolve the error, use
app.Run
instead of app.Use
. MVC doesn’t buffer IAsyncEnumerable
types when using System.Text.Json
Breaking ChangeWhen formatting using
System.Text.Json
, MVC no longer buffers IAsyncEnumerable<T>
instances. Solution
If your application requires buffering, consider manually buffering the
IAsyncEnumerable<T>
object by using, for example, ToListAsync();
. Core .NET libraries
Nullable reference type annotations changed
Breaking ChangeThe 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)
ImmutableArray<T>.Equals(Object)
EntityHandle.Equals(Object)
GuidHandle.Equals(Object)
Handle.Equals(Object)
Label.Equals(Object)
DateOnly.Equals(System.Object)
TimeOnly.Equals(System.Object)
Solution
Update code that calls these APIs to reflect the revised nullability contracts.
API obsoletions with non-default diagnostic IDs
Breaking ChangeUse of
WebRequest
, HttpWebRequest
, ServicePoint
, and WebClient
produces 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.
Solution
Use
HttpClient
instead. Older framework versions dropped from package
Breaking ChangeStarting 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
Solution
Upgrade your project to a newer version of .NET
Unhandled exceptions from a BackgroundService
Breaking ChangeIn 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.
Solution
If you prefer to keep the previous behavior of allowing an unhandled exception in a
BackgroundService
to not stop the Host, you can set HostOptions.BackgroundServiceExceptionBehavior
to BackgroundServiceExceptionBehavior.Ignore
. System.Text.Json
IAsyncEnumerable
serialization
Breaking ChangeAsynchronous 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 NotSupportedException
. Solution
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
JsonIgnoreAttribute
to the property containing theIAsyncEnumerable<T>
. - 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 disallowed
Breaking ChangeModels 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
Solution
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.