title | author | description | ms.author | ms.date | uid |
---|---|---|---|---|---|
Migrate from ASP.NET Core 7.0 to 8.0 |
rick-anderson |
Learn how to migrate an ASP.NET Core 6 project to ASP.NET Core 8.0 |
riande |
10/13/2022 |
migration/70-to-80 |
This article explains how to update an existing ASP.NET Core 7.0 project to ASP.NET Core 8.0
If you rely on a global.json
file to target a specific .NET Core SDK version, update the version
property to the .NET 8.0 SDK version that's installed. For example:
{
"sdk": {
- "version": "7.0.100"
+ "version": "8.0.100"
}
}
Update the project file's Target Framework Moniker (TFM) to net8.0
:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
- <TargetFramework>net7.0</TargetFramework>
+ <TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
</Project>
In the project file, update each Microsoft.AspNetCore.*
, Microsoft.EntityFrameworkCore.*
, Microsoft.Extensions.*
, and System.Net.Http.Json
package reference's Version
attribute to 8.00 or later. For example:
<ItemGroup>
- <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="7.0.12" />
- <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.12" />
- <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
- <PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
+ <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="8.0.0" />
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0">
+ <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
+ <PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
</ItemGroup>
The following migration scenarios are covered:
- Update a Blazor Server app
- Adopt all Blazor Web App conventions
- Convert a Blazor Server app into a Blazor Web App
- Update a Blazor WebAssembly app
- Convert a hosted Blazor WebAssembly app into a Blazor Web App
- Update service and endpoint option configuration
- Drop Blazor Server with Yarp routing workaround
- Migrate
CascadingValue
components in layout components - Migrate the
BlazorEnableCompression
MSBuild property - Migrate the
<CascadingAuthenticationState>
component to cascading authentication state services - New article: HTTP caching issues during migration
For guidance on adding Blazor support to an ASP.NET Core app, see xref:blazor/components/integration#add-blazor-support-to-an-aspnet-core-app.
We recommend using Blazor Web Apps in .NET 8, but Blazor Server is supported. To continue using Blazor Server with .NET 8, follow the guidance in the first three sections of this article:
New Blazor features introduced for Blazor Web Apps aren't available to a Blazor Server app updated to run under .NET 8. If you wish to adopt the new .NET 8 Blazor features, follow the guidance in either of the following sections:
To optionally adopt all of the new Blazor Web App conventions, we recommend the following process:
- Create a new app from the Blazor Web App project template. For more information, see xref:blazor/tooling.
- Move the your app's components and code to the new Blazor Web App app, making modifications to adopt new features.
- Update the layout and styles of the Blazor Web App.
New .NET 8 features are covered in xref:aspnetcore-8#blazor. When updating an app from .NET 6 or earlier, see the migration and release notes (What's new articles) for intervening releases.
Blazor Server apps are supported in .NET 8 without any code changes. Use the following guidance to convert a Blazor Server app into an equivalent .NET 8 Blazor Web App, which makes all of the new .NET 8 features available.
Important
This section focuses on the minimal changes required to convert a .NET 7 Blazor Server app into a .NET 8 Blazor Web App. To adopt all of the new Blazor Web App conventions, follow the guidance in the Adopt all Blazor Web App conventions section.
-
Follow the guidance in the first three sections of this article:
-
Move the contents of the
App
component (App.razor
) to a newRoutes
component file (Routes.razor
) added to the project's root folder. Leave the emptyApp.razor
file in the app in the project's root folder. -
Add an entry to the
_Imports.razor
file to make shorthand render modes available to the app:@using static Microsoft.AspNetCore.Components.Web.RenderMode
-
Move the content in the
_Host
page (Pages/_Host.cshtml
) to the emptyApp.razor
file. Proceed to make the following changes to theApp
component.[!NOTE] In the following example, the project's namespace is
BlazorServerApp
. Adjust the namespace to match your project.Remove the following lines from the top of the file:
- @page "/" - @using Microsoft.AspNetCore.Components.Web - @namespace BlazorServerApp.Pages - @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Replace the preceding lines with a line that injects an xref:Microsoft.Extensions.Hosting.IHostEnvironment instance:
@inject IHostEnvironment Env
Remove the tilde (
~
) from thehref
of the<base>
tag and replace with the base path for your app:- <base href="~/" /> + <base href="/" />
Remove the Component Tag Helper for the
HeadOutlet
component and replace it with theHeadOutlet
component.Remove the following line:
- <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
Replace the preceding line with the following:
<HeadOutlet @rendermode="InteractiveServer" />
Remove the Component Tag Helper for the
App
component and replace it with theRoutes
component.Remove the following line:
- <component type="typeof(App)" render-mode="ServerPrerendered" />
Replace the preceding line with the following:
<Routes @rendermode="InteractiveServer" />
[!NOTE] The preceding configuration assumes that the app's components adopt interactive server rendering. For more information, including how to adopt static server rendering, see xref:blazor/components/render-modes.
Remove the Environment Tag Helpers for error UI and replace them with the following Razor markup.
Remove the following lines:
- <environment include="Staging,Production"> - An error has occurred. This application may no longer respond until reloaded. - </environment> - <environment include="Development"> - An unhandled exception has occurred. See browser dev tools for details. - </environment>
Replace the preceding lines with the following:
@if (Env.IsDevelopment()) { <text> An unhandled exception has occurred. See browser dev tools for details. </text> } else { <text> An error has occurred. This app may no longer respond until reloaded. </text> }
Change the Blazor script from
blazor.server.js
toblazor.web.js
:- <script src="_framework/blazor.server.js"></script> + <script src="_framework/blazor.web.js"></script>
-
Delete the
Pages/_Host.cshtml
file. -
Update
Program.cs
:[!NOTE] In the following example, the project's namespace is
BlazorServerApp
. Adjust the namespace to match your project.Add a
using
statement to the top of the file for the project's namespace:using BlazorServerApp;
Replace
AddServerSideBlazor
withAddRazorComponents
and a chained call toAddInteractiveServerComponents
.Remove the following line:
- builder.Services.AddServerSideBlazor();
Replace the preceding line with Razor component and interactive server component services:
builder.Services.AddRazorComponents() .AddInteractiveServerComponents();
Remove the following line:
- app.MapBlazorHub();
Replace the preceding line with a call to
MapRazorComponents
, supplying theApp
component as the root component type, and add a chained call toAddInteractiveServerRenderMode
:app.MapRazorComponents<App>() .AddInteractiveServerRenderMode();
Remove the following line:
- app.MapFallbackToPage("/_Host");
Add Antiforgery Middleware to the request processing pipeline after the call to
app.UseRouting
. If there are calls toapp.UseRouting
andapp.UseEndpoints
, the call toapp.UseAntiforgery
must go between them. A call toapp.UseAntiforgery
must be placed after calls toapp.UseAuthentication
andapp.UseAuthorization
.app.UseAntiforgery();
-
If the Blazor Server app was configured to disable prerendering, you can continue to disable prerendering for the updated app. In the
App
component, change the value assigned to the@rendermode
Razor directive attributes for theHeadOutlet
andRoutes
components.Change the value of the
@rendermode
directive attribute for both theHeadOutlet
andRoutes
components to disable prerendering:- @rendermode="InteractiveServer" + @rendermode="new InteractiveServerRenderMode(prerender: false)"
For more information, see xref:blazor/components/render-modes?view=aspnetcore-8.0&preserve-view=true#prerendering.
Follow the guidance in the first three sections of this article:
Blazor WebAssembly apps are supported in .NET 8 without any code changes. Use the following guidance to convert an ASP.NET Core hosted Blazor WebAssembly app into an equivalent .NET 8 Blazor Web App, which makes all of the new .NET 8 features available.
Important
This section focuses on the minimal changes required to convert a .NET 7 ASP.NET Core hosted Blazor WebAssembly app into a .NET 8 Blazor Web App. To adopt all of the new Blazor Web App conventions, follow the guidance in the Adopt all Blazor Web App conventions section.
-
Follow the guidance in the first three sections of this article:
[!IMPORTANT] Using the preceding guidance, update the
Client
,Server
, andShared
projects of the solution. -
Move the file content from the
Client/wwwroot/index.html
file to a newApp
component file (App.razor
) created at the root of theServer
project. After you move the file's contents, delete theindex.html
file. -
Rename
App.razor
in theClient
project toRoutes.razor
. -
In
Routes.razor
, update the value of theAppAssembly
attribute totypeof(Program).Assembly
. -
Add an entry to the
_Imports.razor
file to make shorthand render modes available to the app:@using static Microsoft.AspNetCore.Components.Web.RenderMode
-
Make a copy of the
_Imports.razor
file and add it to theServer
project. -
Make the following changes to the
App.razor
file:Replace the
<title>
tag with theHeadOutlet
component. Start by removing the<title>
tag:- <title>...</title>
Add the
HeadOutlet
component at the end of the<head>
content with the interactive WebAssembly render mode and prerendering disabled:<HeadOutlet @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" />
Replace the following
div
tag with theRoutes
component using the interactive WebAssembly render mode and prerendering disabled:- <div id="app"> - ... - </div>
Replace the preceding markup with the following:
<Routes @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)"
Update the
blazor.webassembly.js
script toblazor.web.js
:- <script src="_framework/blazor.webassembly.js"></script> + <script src="_framework/blazor.web.js"></script>
-
Remove the following lines from
Client/Program.cs
:- builder.RootComponents.Add<App>("#app"); - builder.RootComponents.Add<HeadOutlet>("head::after");
-
Update
Server/Program.cs
:Add Razor component and interactive WebAssembly component services to the project. Call
AddRazorComponents
with a chained call toAddInteractiveWebAssemblyComponents
:builder.Services.AddRazorComponents() .AddInteractiveWebAssemblyComponents();
Add Antiforgery Middleware to the request processing pipeline immediately after the call to
app.UseRouting
. If there are calls toapp.UseRouting
andapp.UseEndpoints
, the call toapp.UseAntiforgery
must go between them. Calls toapp.UseAntiforgery
must be placed after calls toapp.UseAuthentication
andapp.UseAuthorization
.app.UseAntiforgery();
Remove the following line:
- app.UseBlazorFrameworkFiles();
Remove the following line:
- app.MapFallbackToFile("index.html");
Replace the preceding line with a call to
MapRazorComponents
, supplying theApp
component as the root component type, and add chained calls toAddInteractiveWebAssemblyRenderMode
andAddAdditionalAssemblies
:app.MapRazorComponents<App>() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(typeof({CLIENT APP NAMESPACE}._Imports).Assembly);
In the preceding example, the
{CLIENT APP NAMESPACE}
placeholder is the namespace of theClient
project (for example,HostedBlazorApp.Client
). Replace the placeholder with theClient
project's namespace. -
Run the solution from the
Server
project:For Visual Studio, confirm that the
Server
project is selected in Solution Explorer when running the app.If using the .NET CLI, run the project from the
Server
project's folder.
With the release of Blazor Web Apps in .NET 8, Blazor service and endpoint option configuration is updated with the introduction of new API for interactive component services and component endpoint configuration.
Updated configuration guidance appears in the following locations:
- Server-side circuit handler options: Covers new Blazor-SignalR circuit and hub options configuration.
- Render Razor components from JavaScript: Covers dynamic component registration with xref:Microsoft.AspNetCore.Components.Web.JSComponentConfigurationExtensions.RegisterForJavaScript%2A.
- Blazor custom elements: Blazor Web App registration: Covers root component custom element registration with
RegisterCustomElement
. - Prefix for Blazor WebAssembly assets: Covers control of the path string that indicates the prefix for Blazor WebAssembly assets.
- Temporary redirection URL validity duration: Covers control of the lifetime of data protection validity for temporary redirection URLs emitted by Blazor server-side rendering.
- Detailed errors: Covers enabling detailed errors for Razor component server-side rendering.
- Prerendering configuration: Prerendering is enabled by default for Blazor Web Apps. Follow this link for guidance on how to disable prerendering if you have special circumstances that require an app to disable prerendering.
If you previously followed the guidance in xref:migration/inc/blazor?view=aspnetcore-7.0&preserve-view=true for migrating a Blazor Server app with Yarp to .NET 6 or .NET 7, you can reverse the workaround steps that you took when following the article's guidance. Routing and deep linking for Blazor Server with Yarp work correctly in .NET 8.
Cascading parameters don't pass data across render mode boundaries, and layouts are statically rendered in otherwise interactive apps. Therefore, apps that seek to use cascading parameters in interactively rendered components won't be able to cascade the values from a layout.
The two approaches for migration are:
- (Recommended) Pass the state as a root-level cascading value. For more information, see Root-level cascading values.
- Wrap the router in the
Routes
component with theCascadingValue
component and make theRoutes
component interactively rendered. For an example, seeCascadingValue
component.
For more information, see Cascading values/parameters and render mode boundaries.
For Blazor WebAssembly apps that disable compression and target .NET 7 or earlier but are built with the .NET 8 SDK, the BlazorEnableCompression
MSBuild property has changed to CompressionEnabled
:
<PropertyGroup>
- <BlazorEnableCompression>false</BlazorEnableCompression>
+ <CompressionEnabled>false</CompressionEnabled>
</PropertyGroup>
When using the .NET CLI publish command, use the new property:
dotnet publish -p:CompressionEnabled=false
For more information, see the following resources:
- Static Web Assets Compression Flag Breaking Change (dotnet/announcements #283)
- xref:blazor/host-and-deploy/webassembly?view=aspnetcore-8.0&preserve-view=true#compression
In .NET 7 or earlier, the xref:Microsoft.AspNetCore.Components.Authorization.CascadingAuthenticationState component is wrapped around some part of the UI tree, for example around the Blazor router, to provide cascading authentication state:
<CascadingAuthenticationState>
<Router ...>
...
</Router>
</CascadingAuthenticationState>
In .NET 8, don't use the xref:Microsoft.AspNetCore.Components.Authorization.CascadingAuthenticationState component:
- <CascadingAuthenticationState>
<Router ...>
...
</Router>
- </CascadingAuthenticationState>
Instead, add cascading authentication state services to the service collection by calling xref:Microsoft.Extensions.DependencyInjection.CascadingAuthenticationStateServiceCollectionExtensions.AddCascadingAuthenticationState%2A in the Program
file:
builder.Services.AddCascadingAuthenticationState();
For more information, see the following resources:
- ASP.NET Core Blazor authentication and authorization article
AuthenticationStateProvider
service- Expose the authentication state as a cascading parameter
- Customize unauthorized content with the Router component
- xref:blazor/security/server/index#implement-a-custom-authenticationstateprovider
We've added a new article that discusses some of the common HTTP caching issues that can occur when upgrading Blazor apps across major versions and how to address HTTP caching issues.
For more information, see xref:blazor/http-caching-issues.
For apps using Docker, update the Dockerfile FROM
statements and scripts. Use a base image that includes the ASP.NET Core 8.0 runtime. Consider the following docker pull
command difference between ASP.NET Core 7.0 and 8.0:
- docker pull mcr.microsoft.com/dotnet/aspnet:7.0
+ docker pull mcr.microsoft.com/dotnet/aspnet:8.0
The default ASP.NET Core port configured in .NET container images has been updated from port 80 to 8080.
The new ASPNETCORE_HTTP_PORTS
environment variable was added as a simpler alternative to ASPNETCORE_URLS
.
For more information, see:
For breaking changes from .NET Core .NET 7.0 to 8.0, see Breaking changes in .NET 8, which includes ASP.NET Core and Entity Framework Core sections.