--- title: Migrate from ASP.NET Core 3.1 to 5.0 author: scottaddie 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: 11/10/2020 no-loc: [appsettings.json, "ASP.NET Core Identity", cookie, Cookie, Blazor, "Blazor Server", "Blazor WebAssembly", "Identity", "Let's Encrypt", Razor, SignalR] uid: migration/31-to-50 --- # Migrate from ASP.NET Core 3.1 to 5.0 By [Scott Addie](https://github.com/scottaddie) This article explains how to update an existing ASP.NET Core 3.1 project to ASP.NET Core 5.0. ## 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 ``` ## Update Blazor WebAssembly projects 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 - + ``` 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). ### Standalone Blazor WebAssembly app with Microsoft Accounts For a standalone Blazor WebAssembly app registered in the Azure portal to use Azure Active Directory (AAD) 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, set the platform configuration to **Single-page application** with the app's redirect URI. * Also in the **Authentication** blade, disable **Implicit grant** for **Access tokens** and **ID tokens**. For more information, see . ### Standalone Blazor WebAssembly app with Azure Active Directory (AAD) For a standalone Blazor WebAssembly app registered in the Azure portal to use Azure Active Directory (AAD): * 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, set the platform configuration to **Single-page application** with the app's redirect URI. * Also in the **Authentication** blade, disable **Implicit grant** for **Access tokens** and **ID tokens**. For more information, see . ### Standalone Blazor app with Azure Active Directory (AAD) B2C 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, set the platform configuration to **Single-page application** with the app's redirect URI. * Also in the **Authentication** blade, disable **Implicit grant** for **Access tokens** and **ID tokens**. For more information, see . ### Hosted Blazor WebAssembly app with Azure Active Directory (AAD) or B2C 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: 1. In the Azure portal app registration for the *`Client`* app, 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 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 Azure Active Directory (AAD) or B2C should adopt new Microsoft Identity v2.0 packages: For AAD: ```diff - + + ``` For AAD B2C: ```diff - + + ``` For more information, see: * * ### Unauthorized client for Azure Active Directory (AAD) 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 package references In the project file, update each [Microsoft.AspNetCore.*](https://www.nuget.org/packages?q=Microsoft.AspNetCore.*), [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(); ``` ## 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.