George Kosmidis

Microsoft MVP | Speaks of Azure, AI & .NET | Founder of Munich .NET
Building tomorrow @
slalom
slalom

.NET 6, A guide for the high impact Breaking Changes

by George Kosmidis / Published 3 years and 1 month ago
.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 Change
The 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 Change
A 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 Change
When 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 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)
  • ImmutableArray<T>.Equals(Object)
  • EntityHandle.Equals(Object)
  • GuidHandle.Equals(Object)
  • Handle.Equals(Object)
  • Label.Equals(Object)
  • DateOnly.Equals(System.Object)
  • TimeOnly.Equals(System.Object)
For a full list visit Microsoft Docs.
Solution
Update code that calls these APIs to reflect the revised nullability contracts.

API obsoletions with non-default diagnostic IDs

Breaking Change
Use 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 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

Solution
Upgrade your project to a newer version of .NET

Unhandled exceptions from a BackgroundService

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.
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 Change
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 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 the IAsyncEnumerable<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 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
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.
This page is open source. Noticed a typo? Or something unclear?
Edit Page Create Issue Discuss
Microsoft MVP - George Kosmidis
Azure Architecture Icons - SVGs, PNGs and draw.io libraries