Migrate from ASP.NET Core in .NET 8 to ASP.NET Core in .NET 9
This article explains how to update an ASP.NET Core in .NET 8 to ASP.NET Core in .NET 9.
Prerequisites
Visual Studio 2022 with the ASP.NET and web development workload.
Update the .NET SDK version in global.json
If you rely on a global.json
file to target a specific .NET Core SDK version, update the version
property to the .NET 9.0 SDK version that's installed. For example:
{
"sdk": {
- "version": "8.0.100"
+ "version": "9.0.100"
}
}
Update the target framework
Update the project file's Target Framework Moniker (TFM) to net9.0
:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
- <TargetFramework>net8.0</TargetFramework>
+ <TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
</Project>
Update package references
In the project file, update each Microsoft.AspNetCore.*
, Microsoft.EntityFrameworkCore.*
, Microsoft.Extensions.*
, and System.Net.Http.Json
package reference's Version
attribute to 9.0.0 or later. For example:
<ItemGroup>
- <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="8.0.2" />
- <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.2" />
- <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
- <PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
+ <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="9.0.0" />
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.0" />
+ <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.0" />
+ <PackageReference Include="System.Net.Http.Json" Version="9.0.0" />
</ItemGroup>
Replace UseStaticFiles
with MapStaticAssets
Optimize the handling of static files in your web apps by replacing UseStaticFiles with MapStaticAssets in the app's Program
file:
- app.UseStaticFiles();
+ app.MapStaticAssets();
In MVC & Razor Pages apps you additionally need to chain a call to .WithStaticAssets
after MapRazorPages
or MapControllerRoute
in Program.cs
. For an example, see the Static files in ASP.NET Core.
ASP.NET Core automatically fingerprints and precompresses your static files at build and publish time, and then MapStaticAssets surfaces the optimized files as endpoints using endpoint routing with appropriate caching headers.
To resolve the fingerprinted file names from your app:
In Blazor apps, use the ComponentBase.Assets property. Update explicit references to static assets in Razor component files (
.razor
) to use@Assets["{ASSET PATH}"]
, where the{ASSET PATH}
placeholder is the path to the asset. Note that this should NOT be done for the Blazor framework scripts (blazor.*.js
). In the following example, Bootstrap, the Blazor project template app stylesheet (app.css
), and the CSS isolation stylesheet (based on an app's namespace ofBlazorSample
) are linked in a root component, typically theApp
component (Components/App.razor
):<link rel="stylesheet" href="@Assets["bootstrap/bootstrap.min.css"]" /> <link rel="stylesheet" href="@Assets["app.css"]" /> <link rel="stylesheet" href="@Assets["BlazorSample.styles.css"]" />
In MVC & Razor Pages apps, the script and link tag helpers will automatically resolve the fingerprinted file names.
To resolve the fingerprinted file names when importing JavaScript modules, add a generated import map:
In Blazor apps, add the (ImportMap) component to the
<head>
content of the app's root component, typically in theApp
component (App.razor
):<ImportMap />
In MVC & Razor pages apps, add
<script type="importmap"></script>
to the head of the main layout file, which is updated by the Import Map Tag Helper.
For more information, see the following resources:
Blazor
Adopt simplified authentication state serialization for Blazor Web Apps
Blazor Web Apps can optionally adopt simplified authentication state serialization.
In the server project:
Remove the Persisting Authentication State Provider (
PersistingAuthenticationStateProvider.cs
).Remove the service registration from the
Program
file. Instead, chain a call to AddAuthenticationStateSerialization on AddRazorComponents:- builder.Services.AddScoped<AuthenticationStateProvider, PersistingAuthenticationStateProvider>(); builder.Services.AddRazorComponents() .AddInteractiveServerComponents() .AddInteractiveWebAssemblyComponents() + .AddAuthenticationStateSerialization();
The API only serializes the server-side name and role claims for access in the browser. To include all claims, set SerializeAllClaims to true
:
.AddAuthenticationStateSerialization(options => options.SerializeAllClaims = true);
In the client project (.Client
):
Remove the Persistent Authentication State Provider (
PersistentAuthenticationStateProvider.cs
).Remove the service registration from the
Program
file. Instead, call AddAuthenticationStateDeserialization on the service collection:- builder.Services.AddSingleton<AuthenticationStateProvider, PersistentAuthenticationStateProvider>(); + builder.Services.AddAuthenticationStateDeserialization();
For more information, see What's new in ASP.NET Core 9.0.