Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article explains how to update an ASP.NET Core in .NET 10 to ASP.NET Core in .NET 11.
Prerequisites
Visual Studio 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 SDK version, update the version property to the .NET 11 SDK version that's installed. For example:
{
"sdk": {
- "version": "10.0.102"
+ "version": "11.0.100"
}
}
Update the target framework
Update the project file's Target Framework Moniker (TFM) to net11.0:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
- <TargetFramework>net10.0</TargetFramework>
+ <TargetFramework>net11.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 11.0.0 or later. For example:
<ItemGroup>
- <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="10.0.0" />
- <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.0" />
- <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="10.0.0" />
- <PackageReference Include="System.Net.Http.Json" Version="10.0.0" />
+ <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="11.0.0" />
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="11.0.0" />
+ <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="11.0.0" />
+ <PackageReference Include="System.Net.Http.Json" Version="11.0.0" />
</ItemGroup>
Blazor
Blazor release notes
For new feature coverage, see What's new in ASP.NET Core in .NET 11.
Adopt Inline JS event handler removed from the NavMenu component
This section only applies to Blazor Web Apps.
The inline JS event handler for the navigation bar toggler isn't present in the NavMenu component of the Blazor Web App project template in .NET 11 or later. Apps generated from the project template use a collocated JS module approach to show or hide the navigation links on the rendered page. The approach improves Content Security Policy (CSP) compliance because it doesn't require the CSP to include an unsafe hash for the inline JS.
Use the following instructions to adopt the new JS module approach for the navigation links toggler in an existing app.
Add a collocated JS module next to the app's NavMenu component.
NavMenu.razor.js:
// Handle navigation menu toggle
const navScrollable = document.getElementById("nav-scrollable");
const navToggler = document.querySelector(".navbar-toggler");
if (navScrollable && navToggler) {
navScrollable.addEventListener("click", function() {
navToggler.click();
});
}
At the top of the app's NavMenu component (NavMenu.razor), add a <script> tag for the collocated JS module:
- If the app adopts client-side rendering (has a
.Clientproject) with global interactivity (the render mode is set globally for the app by the app'sAppcomponent), use the following tag, which indicates the path to the module in theLayoutfolder:
<script type="module" src="@Assets["Layout/NavMenu.razor.js"]"></script>
- Otherwise, use the following tag, which indicates the path to the module in the
Components/Layoutfolder:
<script type="module" src="@Assets["Components/Layout/NavMenu.razor.js"]"></script>
Also in the app's NavMenu component, change the line that has the inline JS to toggle the navigation links:
- <div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
+ <div id="nav-scrollable" class="nav-scrollable">
If the app has a Content Security Policy (CSP) with an unsafe hash for the inline JS removed by the preceding step, remove the unsafe hash:
- 'unsafe-hashes' 'sha256-qnHnQs7NjQNHHNYv/I9cW+I62HzDJjbnyS/OFzqlix0='
QuickGrid adopts URL-based pagination and sorting
QuickGrid component persists pagination and sort state in the URL query string (for example, ?page=2&sort=Name&order=asc), which enables link sharing, browser back/forward navigation, and operation under static server-side rendering (static SSR). This behavior is enabled by default.
To work without a JavaScript runtime, sortable column headers and paginator controls now render as <a> (link) elements instead of <button> elements. Update any custom CSS that targets the previous markup:
- button.col-title { ... }
+ button.col-title, a.col-title { ... }
- nav button:disabled { ... }
+ nav button:disabled, nav a[aria-disabled="true"] { ... }
Disabled paginator links use aria-disabled="true" instead of the HTML disabled attribute, which isn't valid on <a> elements. The built-in QuickGrid CSS already covers both markup styles.
When more than one QuickGrid is rendered on the same page, set a unique QueryParameterNamePrefix on each grid (and give each its own PaginationState) to prevent the grids from sharing the page, sort, and order query parameters:
- <QuickGrid Items="@cities" Pagination="@pagination2">...</QuickGrid>
+ <QuickGrid Items="@cities" Pagination="@pagination2" QueryParameterNamePrefix="cities">...</QuickGrid>
To revert to the previous <button>-based markup, which requires an interactive render mode, set the following AppContext switch to false:
AppContext.SetSwitch(
"Microsoft.AspNetCore.Components.QuickGrid.EnableUrlBasedQuickGridNavigationAndSorting",
false);
The switch only controls the rendered HTML element; sort and page state is read from and written to the URL query string regardless of the setting.
Security
Automatic CSRF protection
.NET 11 adds automatic Cross-Site Request Forgery (CSRF) protection. When an app is built with WebApplication.CreateBuilder and has endpoints, a middleware is wired up by default that inspects the Sec-Fetch-Site and Origin headers and records a validation verdict on the request.
The middleware validates endpoints that opt in to antiforgery validation—that is, endpoints with metadata implementing IAntiforgeryMetadata where RequiresValidation is true. The framework sets this automatically for:
- All Blazor server-side rendering (SSR) endpoints. Each is protected by default; a page can opt out with
@attribute [RequireAntiforgeryToken(false)]. - Minimal API endpoints that bind form data.
- MVC actions that use antiforgery validation, such as those annotated with
[ValidateAntiForgeryToken]or[AutoValidateAntiforgeryToken].
Endpoints that bind JSON, such as a plain MapPost or a Web API [HttpPost] action, have no behavioral change.
Going forward, the automatic CSRF protection is the recommended defense, and most apps no longer need the token-based antiforgery system. Keep the token-based system when the app must support browsers that don't send Sec-Fetch-Site, uses IAntiforgeryAdditionalDataProvider, or must keep the token defense as an independent layer for a compliance requirement. Both protections can coexist.
To simplify an app that configures antiforgery explicitly, drop the AddAntiforgery and UseAntiforgery calls and rely on the automatic protection. For most apps, this is a one-line change with no other code updates. For Blazor static SSR, removing app.UseAntiforgery() also stops antiforgery token generation for rendered forms; see Blazor server-side rendering defers antiforgery validation to middleware.
A 400 - Bad Request on a cross-origin form post is the CSRF protection working as intended. When the request comes from a legitimate origin, allow that origin rather than suppressing the check:
- Configure CORS so the endpoint's resolved policy includes the caller's origin. The CSRF middleware honors that policy and allows the request.
- Only opt an endpoint out with
.DisableAntiforgery()(Minimal APIs) or[IgnoreAntiforgeryToken](MVC) when it isn't vulnerable to CSRF, such as an endpoint that isn't reachable from a browser or that authenticates with a non-cookie mechanism (for example, bearer authentication).
For a full description of the middleware, the validation rules, and how it interacts with the token-based antiforgery system, see Automatic CSRF protection in ASP.NET Core.
Breaking changes
Use the articles in Breaking changes in .NET to find breaking changes that might apply when upgrading an app to a newer version of .NET.
ASP.NET Core