--- title: Migrate from ASP.NET Core 3.1 to 5.0 author: rick-anderson description: Learn how to migrate an ASP.NET Core 3.1 project to ASP.NET Core 5.0. ms.author: scaddie ms.custom: mvc ms.date: 12/02/2020 uid: migration/31-to-50 --- # Migrate from ASP.NET Core 3.1 to 5.0 This article explains how to update an existing ASP.NET Core 3.1 project to ASP.NET Core 5.0. For instructions on how to migrate from ASP.NET Core 3.1 to ASP.NET Core 6.0, see . ## Prerequisites # [Visual Studio](#tab/visual-studio) [!INCLUDE[](~/includes/net-core-prereqs-vs-5.0.md)] # [Visual Studio Code](#tab/visual-studio-code) [!INCLUDE[](~/includes/net-core-prereqs-vsc-5.0.md)] # [Visual Studio for Mac](#tab/visual-studio-mac) [!INCLUDE[](~/includes/net-core-prereqs-mac-5.0.md)] --- ## Update .NET Core SDK version in global.json If you rely upon a [global.json](/dotnet/core/tools/global-json) file to target a specific .NET Core SDK version, update the `version` property to the .NET 5.0 SDK version that's installed. For example: ```diff { "sdk": { - "version": "3.1.200" + "version": "5.0.100" } } ``` ## Update the target framework If updating a Blazor WebAssembly project, skip to the [Update Blazor WebAssembly projects](#update-blazor-webassembly-projects) section. For any other ASP.NET Core project type, update the project file's [Target Framework Moniker (TFM)](/dotnet/standard/frameworks) to `net5.0`: ```diff - netcoreapp3.1 + net5.0 ``` ## Delete `bin` and `obj` folders You may need to delete the `bin` and `obj` folders. Run `dotnet nuget locals --clear all` to clear the NuGet package cache. ## Changes to Blazor app routing logic in 5.0.1 and further 5.x releases up to 6.0 The computation of route precedence changed in the ASP.NET Core 5.0.1 patch release. This might affect you if you've defined catch-all routes or routes with optional parameters. ### Old behavior With the prior behavior in ASP.NET Core 5.0.0 or earlier, routes with lower precedence, such as `{*slug}`, are matched before routes with higher precedence, such as `/customer/{id}`. ### New behavior The new behavior in ASP.NET Core 5.0.1 or later more closely matches the routing behavior defined in ASP.NET Core apps, where the framework computes and establishes the route precedence for each segment first and only uses the length of the route to break ties as a secondary criteria. ### Reason for change The original behavior is considered a bug in the implementation because our goal is for the Blazor routing system to behave in the same way as the ASP.NET Core routing system for the subset of features supported by Blazor routing. ### Recommended action Add the `PreferExactMatches` attribute to the `Router` component in the `App.razor` file to opt into the correct behavior: ```razor ``` When `PreferExactMatches` is set to `@true`, route matching prefers exact matches over wildcards. > [!IMPORTANT] > All apps should explicitly set `PreferExactMatches` to `@true`. > > The ability to set `PreferExactMatches` to `@false` or leave it unset *is only provided for backward compatibility*. > > When .NET 6 is released, the router will always prefer exact matches, and the `PreferExactMatches` option won't be available. ## Update Blazor WebAssembly and Blazor Server projects *The guidance in this section applies to both Blazor hosting models. Sections following this section provide additional guidance specific to hosting models and app types. Apply the guidance from all relevant sections to your app.* 1. In `wwwroot/index.html` of a Blazor WebAssembly app or the `Pages/_Host.cshtml` of a Blazor Server app, add a `` element to the `` element for styles. In the following `` element `href` attribute values, the placeholder `{ASSEMBLY NAME}` is the app's assembly name. ```diff + ``` Standalone Blazor WebAssembly or Blazor Server example: ```diff + ``` *`Client`* project of a hosted Blazor WebAssembly solution example: ```diff + ``` 1. Include a new namespace in the app's `_Imports.razor` file for [component virtualization](xref:blazor/components/virtualization), . The following `_Imports.razor` files show the default namespaces in apps generated from the Blazor project templates. The placeholder `{ASSEMBLY NAME}` is the app's assembly name. Blazor WebAssembly (`_Imports.razor`): ```razor @using System.Net.Http @using System.Net.Http.Json @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.AspNetCore.Components.WebAssembly.Http @using Microsoft.JSInterop @using {ASSEMBLY NAME} @using {ASSEMBLY NAME}.Shared ``` Blazor Server (`_Imports.razor`): ```razor @using System.Net.Http @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using {ASSEMBLY NAME} @using {ASSEMBLY NAME}.Shared ``` 1. In the `MainLayout` component (`Shared/MainLayout.razor`), surround the component's HTML markup with a `
` element that has a `class` attribute set to `page`: ```razor
...
``` 1. Add the following files to the `Shared` folder: `MainLayout.razor.css`: ```css .page { position: relative; display: flex; flex-direction: column; } .main { flex: 1; } .sidebar { background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); } .top-row { background-color: #f7f7f7; border-bottom: 1px solid #d6d5d5; justify-content: flex-end; height: 3.5rem; display: flex; align-items: center; } .top-row ::deep a, .top-row .btn-link { white-space: nowrap; margin-left: 1.5rem; } .top-row a:first-child { overflow: hidden; text-overflow: ellipsis; } @media (max-width: 767.98px) { .top-row:not(.auth) { display: none; } .top-row.auth { justify-content: space-between; } .top-row a, .top-row .btn-link { margin-left: 0; } } @media (min-width: 768px) { .page { flex-direction: row; } .sidebar { width: 250px; height: 100vh; position: sticky; top: 0; } .top-row { position: sticky; top: 0; z-index: 1; } .main > div { padding-left: 2rem !important; padding-right: 1.5rem !important; } } ``` `NavMenu.razor.css`: ```css .navbar-toggler { background-color: rgba(255, 255, 255, 0.1); } .top-row { height: 3.5rem; background-color: rgba(0,0,0,0.4); } .navbar-brand { font-size: 1.1rem; } .oi { width: 2rem; font-size: 1.1rem; vertical-align: text-top; top: -2px; } .nav-item { font-size: 0.9rem; padding-bottom: 0.5rem; } .nav-item:first-of-type { padding-top: 1rem; } .nav-item:last-of-type { padding-bottom: 1rem; } .nav-item ::deep a { color: #d7d7d7; border-radius: 4px; height: 3rem; display: flex; align-items: center; line-height: 3rem; } .nav-item ::deep a.active { background-color: rgba(255,255,255,0.25); color: white; } .nav-item ::deep a:hover { background-color: rgba(255,255,255,0.1); color: white; } @media (min-width: 768px) { .navbar-toggler { display: none; } .collapse { /* Never collapse the sidebar for wide screens */ display: block; } } ``` 1. The latest base `wwwroot/css/app.css` file of a Blazor WebAssembly app or `wwwroot/css/site.css` file of a Blazor Server app includes the following styles. Remove extra styles leaving the following styles and any that you've added to the app. The following stylesheet only includes base styles and does **not** include custom styles added by the developer: ```css html, body { font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; } a, .btn-link { color: #0366d6; } .btn-primary { color: #fff; background-color: #1b6ec2; border-color: #1861ac; } .content { padding-top: 1.1rem; } .valid.modified:not([type=checkbox]) { outline: 1px solid #26b050; } .invalid { outline: 1px solid red; } .validation-message { color: red; } #blazor-error-ui { background: lightyellow; bottom: 0; box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); display: none; left: 0; padding: 0.6rem 1.25rem 0.7rem 1.25rem; position: fixed; width: 100%; z-index: 1000; } #blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 0.75rem; top: 0.5rem; } ``` > [!NOTE] > The preceding example doesn't show the `@import` directive for Open Iconic icons (`open-iconic-bootstrap.css`), provided by the Blazor project template. [Open Iconic](https://github.com/iconic/open-iconic) was abandoned by its maintainers. ## Update Blazor WebAssembly projects Follow the guidance in the preceding [Update Blazor WebAssembly and Blazor Server projects](#update-blazor-webassembly-and-blazor-server-projects) section. For a Blazor WebAssembly project, including the *`Client`* project of a hosted Blazor solution, apply the following changes to the project file: 1. Update the SDK from `Microsoft.NET.Sdk.Web` to `Microsoft.NET.Sdk.BlazorWebAssembly`: ```diff - + ``` > [!NOTE] > This update only applies to standalone Blazor WebAssembly projects and the *`Client`* projects of hosted Blazor solutions. 1. Update the following properties: ```diff - netstandard2.1 - 3.0 + net5.0 ``` 1. Remove the package reference to [Microsoft.AspNetCore.Components.WebAssembly.Build](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.Build): ```diff - ``` 1. Update other packages to their latest versions. The latest versions can be found at [NuGet.org](https://www.nuget.org). 1. In `wwwroot/index.html`, change the element that loads the `App` component to a `
` element with an `id` set to `app`: ```diff -Loading... +
Loading...
``` 1. In `Program.Main` (`Program.cs`), change the reference to the `` element to a CSS selector by adding a hash `#` to it: ```diff -builder.RootComponents.Add("app"); +builder.RootComponents.Add("#app"); ``` 1. In `Program.Main` (`Program.cs`), change a default transient `HttpClient` registration to scoped, if present: ```diff -builder.Services.AddTransient(sp => new HttpClient - { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); +builder.Services.AddScoped(sp => new HttpClient + { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); ``` 1. In `Program.Main` (`Program.cs`) of the **`Client`** app of hosted Blazor solutions: * Optionally, substitute `builder.HostEnvironment.BaseAddress` for string client base addresses. * Change any named transient client factory registrations to scoped. ```diff -builder.Services.AddHttpClient("{APP NAMESPACE}.ServerAPI", - client => client.BaseAddress = new Uri("https://localhost:5001")) - .AddHttpMessageHandler(); -builder.Services.AddTransient(sp => sp.GetRequiredService() - .CreateClient("{APP NAMESPACE}.ServerAPI")); +builder.Services.AddHttpClient("{APP NAMESPACE}.ServerAPI", + client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)) + .AddHttpMessageHandler(); +builder.Services.AddScoped(sp => sp.GetRequiredService() + .CreateClient("{APP NAMESPACE}.ServerAPI")); ``` In the preceding code, the `{APP NAMESPACE}` placeholder is the app's namespace. ### Standalone Blazor WebAssembly app with Microsoft Accounts Follow the guidance in the preceding [Update Blazor WebAssembly and Blazor Server projects](#update-blazor-webassembly-and-blazor-server-projects) and [Update Blazor WebAssembly projects](#update-blazor-webassembly-projects) sections. For a standalone Blazor WebAssembly app registered in the Azure portal to use Microsoft Entra ID (ME-ID) for Microsoft Accounts: * The app requires the `openid` and `offline_access` scopes: ```csharp options.ProviderOptions.DefaultAccessTokenScopes.Add("openid"); options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access"); ``` * In the Azure portal app registration **Authentication** blade: 1. Remove the **Web** platform configuration. 1. Add a **Single-page application** platform configuration with the app's redirect URI. 1. Disable **Implicit grant** for **Access tokens** and **ID tokens**. For more information, see . ### Standalone Blazor WebAssembly app with Microsoft Entra ID (ME-ID) Follow the guidance in the preceding [Update Blazor WebAssembly and Blazor Server projects](#update-blazor-webassembly-and-blazor-server-projects) and [Update Blazor WebAssembly projects](#update-blazor-webassembly-projects) sections. For a standalone Blazor WebAssembly app registered in the Azure portal to use Microsoft Entra ID (ME-ID): * The app requires the `https://graph.microsoft.com/User.Read` scope: ```csharp options.ProviderOptions.DefaultAccessTokenScopes .Add("https://graph.microsoft.com/User.Read"); ``` * In the Azure portal app registration **Authentication** blade: 1. Remove the **Web** platform configuration. 1. Add a **Single-page application** platform configuration with the app's redirect URI. 1. Disable **Implicit grant** for **Access tokens** and **ID tokens**. For more information, see . ### Standalone Blazor WebAssembly app with Azure Active Directory (AAD) B2C Follow the guidance in the preceding [Update Blazor WebAssembly and Blazor Server projects](#update-blazor-webassembly-and-blazor-server-projects) and [Update Blazor WebAssembly projects](#update-blazor-webassembly-projects) sections. For a standalone Blazor WebAssembly app registered in the Azure portal to use Azure Active Directory (AAD) B2C: * The app requires the `openid` and `offline_access` scopes: ```csharp options.ProviderOptions.DefaultAccessTokenScopes.Add("openid"); options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access"); ``` * In the Azure portal app registration **Authentication** blade: 1. Remove the **Web** platform configuration. 1. Add a **Single-page application** platform configuration with the app's redirect URI. 1. Disable **Implicit grant** for **Access tokens** and **ID tokens**. For more information, see . ### Hosted Blazor WebAssembly app with Microsoft Entra ID (ME-ID) or AAD B2C Follow the guidance in the preceding [Update Blazor WebAssembly and Blazor Server projects](#update-blazor-webassembly-and-blazor-server-projects) and [Update Blazor WebAssembly projects](#update-blazor-webassembly-projects) sections. The *`Client`* app registration of a hosted Blazor solution that uses AAD or AAD B2C for user authentication should use a **Single-page application** Azure Apps platform configuration. In the Azure portal *`Client`* app registration **Authentication** blade: 1. Remove the **Web** platform configuration. 1. Add a **Single-page application** platform configuration with the app's redirect URI. 1. Disable **Implicit grant** for **Access tokens** and **ID tokens**. For more information, see: * * ### Update the Server project of a hosted Blazor solution Follow the guidance in the preceding sections: * [Update Blazor WebAssembly and Blazor Server projects](#update-blazor-webassembly-and-blazor-server-projects) * [Update Blazor WebAssembly projects](#update-blazor-webassembly-projects) * The section that applies to the app's provider with Azure Active Directory: * [Standalone Blazor WebAssembly app with Microsoft Accounts](#standalone-blazor-webassembly-app-with-microsoft-accounts) * [Standalone Blazor WebAssembly app with Microsoft Entra ID (ME-ID)](#standalone-blazor-webassembly-app-with-microsoft-entra-id-me-id) * [Standalone Blazor WebAssembly app with Azure Active Directory (AAD) B2C](#standalone-blazor-webassembly-app-with-azure-active-directory-aad-b2c) Update the *`Server`* project of a hosted Blazor solution as an ASP.NET Core app following the general guidance in this article. Additionally, *`Server`* projects that authenticate users to client Blazor WebAssembly apps with Microsoft Entra ID (ME-ID) or B2C should adopt new Microsoft Identity v2.0 packages: For AAD: ```diff - + + ``` For AAD B2C: ```diff - + + ``` For the preceding package references, determine the package versions for the `{VERSION}` placeholders at NuGet.org: * [`Microsoft.Identity.Web`](https://www.nuget.org/packages/Microsoft.Identity.Web) * [`Microsoft.Identity.Web.UI`](https://www.nuget.org/packages/Microsoft.Identity.Web.UI) > [!NOTE] > The SDK of the *`Server`* project in a hosted Blazor WebAssembly solution remains `Microsoft.NET.Sdk.Web`: > > ```xml > > ``` For more information, see: * * ### Clean and rebuild the solution After migrating the app or solution to .NET 5, clean and rebuild the app or solution. If package incompatibilities exist between new package references and cached packages: 1. Clear NuGet package caches by executing the following [`dotnet nuget locals`](/dotnet/core/tools/dotnet-nuget-locals) command in a command shell: ```dotnetcli dotnet nuget locals --clear all ``` 1. Clean and rebuild the app or solution. ### Troubleshoot Follow the *Troubleshoot* guidance at the end of the Blazor WebAssembly security topic that applies to your app: Standalone Blazor WebAssembly apps: * [General guidance for OIDC providers and the WebAssembly Authentication Library](xref:blazor/security/webassembly/standalone-with-authentication-library) * [Microsoft Accounts](xref:blazor/security/webassembly/standalone-with-microsoft-accounts) * [Microsoft Entra ID (ME-ID)](xref:blazor/security/webassembly/standalone-with-microsoft-entra-id) * [Azure Active Directory (AAD) B2C](xref:blazor/security/webassembly/standalone-with-azure-active-directory-b2c) Hosted Blazor WebAssembly apps: * [Microsoft Entra ID (ME-ID)](xref:blazor/security/webassembly/hosted-with-microsoft-entra-id) * [Azure Active Directory (AAD) B2C](xref:blazor/security/webassembly/hosted-with-azure-active-directory-b2c) * [Identity Server](xref:blazor/security/webassembly/hosted-with-identity-server) ### Unauthorized client for Microsoft Entra ID (ME-ID) After upgrading a Blazor WebAssembly app that uses AAD for authentication, you may receive the following error on the login callback to the app after the user signs in with AAD: > info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] > Authorization failed. These requirements were not met: > DenyAnonymousAuthorizationRequirement: Requires an authenticated user. Login callback error from AAD: * Error: `unauthorized_client` * Description: `AADB2C90058: The provided application is not configured to allow public clients.` To resolve the error: 1. In the Azure portal, access the [app's manifest](/azure/active-directory/develop/reference-app-manifest). 1. Set the [`allowPublicClient`](/azure/active-directory/develop/reference-app-manifest#allowpublicclient-attribute) attribute to `null` or `true`. ## Update a Blazor Progressive Web Application (PWA) Add the following item to the PWA app's project file: ```xml ``` ## Remove preview CSS isolation stylesheet link If the project's `wwwroot/index.html` (Blazor WebAssembly) or `Pages/_Host.cshtml` (Blazor Server) contains a stylesheet `` element for `scoped.styles.css` from an earlier 5.0 preview release, remove the `` tag: ```diff - ``` ## Update Razor class libraries (RCLs) Migrate Razor class libraries (RCLs) to take advantage of new APIs or features that are introduced as part of ASP.NET Core 5.0. To update a RCL that targets components: 1. Update the following properties in the project file: ```diff - netstandard2.0 - 3.0 + net5.0 ``` 1. Update other packages to their latest versions. The latest versions can be found at [NuGet.org](https://www.nuget.org). To update an RCL targeting MVC, update the following properties in the project file: ```diff - netcoreapp3.1 + net5.0 true ``` ## Update package references In the project file, update each [Microsoft.AspNetCore.*](https://www.nuget.org/packages?q=Microsoft.AspNetCore.*), [Microsoft.EntityFrameworkCore.*](https://www.nuget.org/packages?q=Microsoft.EntityFrameworkCore.*), [Microsoft.Extensions.*](https://www.nuget.org/packages?q=Microsoft.Extensions.*), and [System.Net.Http.Json](https://www.nuget.org/packages/System.Net.Http.Json) package reference's `Version` attribute to 5.0.0 or later. For example: ```diff - - - - + + + + ``` ## Update Docker images For apps using Docker, update your *Dockerfile* `FROM` statements and scripts. Use a base image that includes the ASP.NET Core 5.0 runtime. Consider the following `docker pull` command difference between ASP.NET Core 3.1 and 5.0: ```diff - docker pull mcr.microsoft.com/dotnet/core/aspnet:3.1 + docker pull mcr.microsoft.com/dotnet/aspnet:5.0 ``` As part of the move to ".NET" as the product name, the Docker images moved from the `mcr.microsoft.com/dotnet/core` repositories to `mcr.microsoft.com/dotnet`. For more information, see [dotnet/dotnet-docker#1939](https://github.com/dotnet/dotnet-docker/issues/1939). ## Model binding changes in ASP.NET Core MVC and Razor Pages ### DateTime values are model bound as UTC times In ASP.NET Core 3.1 and earlier, `DateTime` values were model-bound as local time, where the timezone was determined by the server. `DateTime` values bound from input formatting (JSON) and `DateTimeOffset` values were bound as UTC timezones. In ASP.NET Core 5.0 and later, model binding consistently binds `DateTime` values with the UTC timezone. To retain the previous behavior, remove the `DateTimeModelBinderProvider` in `Startup.ConfigureServices`: ```csharp services.AddControllersWithViews(options => options.ModelBinderProviders.RemoveType()); ``` ### ComplexObjectModelBinderProvider \ ComplexObjectModelBinder replace ComplexTypeModelBinderProvider \ ComplexTypeModelBinder To add support for model binding [C# 9 record types](/dotnet/csharp/whats-new/csharp-9#record-types), the is: * Annotated as obsolete. * No longer registered by default. Apps that rely on the presence of the `ComplexTypeModelBinderProvider` in the `ModelBinderProviders` collection need to reference the new binder provider: ```diff - var complexModelBinderProvider = options.ModelBinderProviders.OfType(); + var complexModelBinderProvider = options.ModelBinderProviders.OfType(); ``` ## UseDatabaseErrorPage obsolete The ASP.NET Core 3.1 templates that include an option for individual user accounts generate a call to . `UseDatabaseErrorPage` is now obsolete and should be replaced with a combination of `AddDatabaseDeveloperPageExceptionFilter` and `UseMigrationsEndPoint`, as shown in the following code: ```diff public void ConfigureServices(IServiceCollection services) { services.AddDbContext(options => options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection"))); + services.AddDatabaseDeveloperPageExceptionFilter(); services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores(); services.AddRazorPages(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); + app.UseMigrationsEndPoint(); - app.UseDatabaseErrorPage(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } ``` For more information, see [this GitHub issue](https://github.com/dotnet/aspnetcore/issues/24987). ## ASP.NET Core Module (ANCM) [!INCLUDE[](~/includes/hosting-bundle.md)] ## Package reference changes affecting some NuGet packages With the migration of some `Microsoft.Extensions.*` NuGet packages from the [dotnet/extensions](https://github.com/dotnet/extensions) repository to [dotnet/runtime](https://github.com/dotnet/runtime), as described in [Migrating dotnet/extensions content to dotnet/runtime and dotnet/aspnetcore (aspnet/Announcements #411)](https://github.com/aspnet/Announcements/issues/411), packaging changes are being applied to some of the migrated packages. These changes often result in namespace changes for .NET API. To research APIs further for app namespace changes when migrating to 5.0, use the [.NET API browser](/dotnet/api/). ## Migrate Microsoft.Identity.Web The following wiki pages explain how to migrate Microsoft.Identity.Web from ASP.NET Core 3.1 to 5.0: * [Microsoft.Identity.Web in web apps](https://github.com/AzureAD/microsoft-identity-web/wiki/web-apps) * [Microsoft.Identity.Web in web APIs](https://github.com/AzureAD/microsoft-identity-web/wiki/web-apis) The following tutorials also explain the migration: * [An ASP.NET Core Web app signing-in users with the Microsoft identity platform in your organization](https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/1-WebApp-OIDC/1-1-MyOrg#option-2-create-the-sample-from-the-command-line). See **Option 2: Create the sample from the command line**. * [Sign-in a user with the Microsoft Identity Platform in a WPF Desktop application and call an ASP.NET Core Web API](https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2/tree/master/1.%20Desktop%20app%20calls%20Web%20API#how-was-the-code-created). See **How was the code created**. ## Review breaking changes For breaking changes from .NET Core 3.1 to .NET 5.0, see [Breaking changes for migration from version 3.1 to 5.0](/dotnet/core/compatibility/3.1-5.0). ASP.NET Core and Entity Framework Core are also included in the list.