Миграция с ASP.NET Core в .NET 10 на ASP.NET Core в .NET 11

В этой статье объясняется, как обновить ASP.NET Core в .NET 10 до ASP.NET Core в .NET 11.

Предпосылки

  • Visual Studio с рабочей нагрузкой ASP.NET и веб-разработки .

    Рабочие нагрузки установщика VS22

Обновите версию .NET SDK в global.json

Если вы используете global.json файл для указания конкретной версии SDK для .NET, обновите version свойство до версии SDK для .NET 11, которая установлена. Рассмотрим пример.

{
  "sdk": {
-    "version": "10.0.102"
+    "version": "11.0.100"
  }
}

Обновление целевой платформы

Обновите идентификатор целевой платформы (TFM) в файле проекта на:net11.0

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
-    <TargetFramework>net10.0</TargetFramework>
+    <TargetFramework>net11.0</TargetFramework>
  </PropertyGroup>

</Project>

Обновление ссылок на пакеты

В файле проекта обновите атрибут Microsoft.AspNetCore.* каждой ссылки на пакет Microsoft.EntityFrameworkCore.*, Microsoft.Extensions.*, System.Net.Http.Json и Version до версии 11.0.0 или выше. Рассмотрим пример.

<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 примечания к выпуску

Сведения о новых возможностях см. в статье "Новые возможности" в ASP.NET Core в .NET 11.

Принятие встроенного обработчика событий JS, удаленного из компонента NavMenu.

Этот раздел применяется только к Blazor Web Apps.

Встроенный JS обработчик событий для переключателя панели навигации отсутствует в NavMenu компоненте Blazor Web App шаблона проекта в .NET 11 или более поздних версиях. Приложения, созданные на основе шаблона проекта, используют подход совместно размещенного JS модуля для отображения или скрытия навигационных ссылок на отображенной странице. Подход повышает соответствие политике безопасности содержимого (CSP), так как для встроенного элемента JS не требуется небезопасный хэш в CSP.

Используйте следующие инструкции, чтобы внедрить новый JS модульный подход для переключателя навигационных ссылок в существующем приложении.

Добавьте сопоставленный JS модуль рядом с компонентом приложения NavMenu.

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();
    });
}

В верхней части компонента приложения NavMenu (NavMenu.razor) добавьте тег <script> для соседнего модуля JS.

  • Если приложение принимает отрисовку на стороне клиента (имеет .Client проект) с глобальным взаимодействием (режим отрисовки устанавливается глобально для приложения компонентом приложения App ), используйте следующий тег, указывающий путь к модулю в папке Layout :
<script type="module" src="@Assets["Layout/NavMenu.razor.js"]"></script>
  • В противном случае используйте следующий тег, указывающий путь к модулю в папке Components/Layout :
<script type="module" src="@Assets["Components/Layout/NavMenu.razor.js"]"></script>

Кроме того, в компоненте приложения NavMenu измените строку со встроенным JS, чтобы переключать ссылки навигации.

- <div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
+ <div id="nav-scrollable" class="nav-scrollable">

Если приложение имеет политику безопасности содержимого (CSP), и у него есть небезопасный хэш для встроенного JS, удаленный на предыдущем шаге, удалите небезопасный хэш:

- 'unsafe-hashes' 'sha256-qnHnQs7NjQNHHNYv/I9cW+I62HzDJjbnyS/OFzqlix0='

QuickGrid принимает разбивку на страницы на основе URL-адресов и сортировку

QuickGrid компонент сохраняет состояние пагинации и сортировки в строке запроса URL (например, ?page=2&sort=Name&order=asc), что позволяет делиться ссылками, использовать навигацию по кнопкам «Назад» и «Вперёд» в браузере и обеспечивает работу при статическом серверном рендеринге (static SSR). Это поведение включено по умолчанию.

Чтобы работать без среды выполнения JavaScript, отсортированные заголовки столбцов и элементы управления с разбивкой на страницы теперь отображаются как <a> элементы (ссылка) вместо <button> элементов. Обновите все пользовательские стили CSS, которые применяются к предыдущей разметке:

- button.col-title { ... }
+ button.col-title, a.col-title { ... }
- nav button:disabled { ... }
+ nav button:disabled, nav a[aria-disabled="true"] { ... }

Отключённые ссылки пагинатора используют aria-disabled="true" вместо HTML-атрибута disabled, который недопустим для элементов <a>. Встроенный QuickGrid CSS уже охватывает оба стиля разметки.

Если на одной странице отображается несколько QuickGrid, задайте для каждой сетки уникальное значение QueryParameterNamePrefix (и присвойте каждой из них собственное значение PaginationState), чтобы сетки не использовали общие параметры запроса страницы, сортировки и порядка сортировки:

- <QuickGrid Items="@cities" Pagination="@pagination2">...</QuickGrid>
+ <QuickGrid Items="@cities" Pagination="@pagination2" QueryParameterNamePrefix="cities">...</QuickGrid>

Чтобы вернуться к предыдущей разметке на основе <button>, для которой требуется интерактивный режим отрисовки, установите для следующего переключателя AppContext значение false:

AppContext.SetSwitch(
    "Microsoft.AspNetCore.Components.QuickGrid.EnableUrlBasedQuickGridNavigationAndSorting",
    false);

Переключатель управляет только визуализируемым HTML-элементом; состояние сортировки и страницы считывается из строки запроса URL и записывается в неё независимо от этой настройки.

Безопасность

Автоматическая защита от CSRF

В .NET 11 добавлена автоматическая защита от межсайтовой подделки запроса (CSRF). Когда приложение создаётся с помощью WebApplication.CreateBuilder и содержит конечные точки, по умолчанию подключается ПО промежуточного слоя, которое проверяет заголовки Sec-Fetch-Site и Origin и записывает результат проверки для запроса.

Промежуточное ПО проверяет конечные точки, для которых явно включена проверка antiforgery, то есть конечные точки с метаданными, реализующими IAntiforgeryMetadata, где RequiresValidation имеет значение true. Платформа автоматически задает этот параметр для следующих компонентов:

  • Все Blazor эндпоинты серверного рендеринга (SSR). Каждая страница по умолчанию защищена; страницу можно исключить с помощью @attribute [RequireAntiforgeryToken(false)].
  • Минимальные эндпоинты API, связанные с данными формы.
  • Действия MVC, использующие проверку защиты от подделки запросов, например, помеченные атрибутами [ValidateAntiForgeryToken] или [AutoValidateAntiforgeryToken].

Конечные точки, привязывающие JSON, такие как простой MapPost или действие Web API [HttpPost], не меняют своего поведения.

В будущем автоматическая защита CSRF является рекомендуемой защитой, и большинство приложений больше не нуждаются в системе защиты на основе маркеров. Сохраняйте систему, основанную на токенах, если приложение должно поддерживать браузеры, которые не отправляют Sec-Fetch-Site, используют IAntiforgeryAdditionalDataProvider, или если защиту на основе токенов необходимо сохранить как независимый уровень для соблюдения нормативных требований. Обе защиты могут сосуществовать.

Чтобы упростить приложение, которое явно настраивает антифоргерию, удалите вызовы AddAntiforgery и UseAntiforgery и используйте автоматическую защиту. Для большинства приложений это однострочный изменение без других обновлений кода. Для Blazor статического SSR удаление app.UseAntiforgery() также прекращает создание antiforgery-токенов для рендерируемых форм; см. Blazor при рендеринге на стороне сервера проверка antiforgery откладывается до промежуточного ПО.

400 - Bad Request при межсайтовой отправке формы означает, что защита CSRF работает как задумано. Когда запрос поступает из доверенного источника, разрешите этот источник вместо отключения проверки:

  • Настройте CORS, чтобы итоговая политика конечной точки включала источник запроса. Промежуточный обработчик CSRF соблюдает эту политику и разрешает запрос.
  • Исключайте конечную точку с помощью .DisableAntiforgery() (минимальных API) или [IgnoreAntiforgeryToken] (MVC) только в том случае, если она не уязвима для CSRF, например если к ней нельзя обратиться из браузера или если в ней используется механизм проверки подлинности, отличный от cookie (например, bearer-аутентификация).

Полное описание промежуточного ПО, правил валидации и того, как оно взаимодействует с системой защиты от подделки запросов на основе токенов, см. в разделе Автоматическая защита CSRF в ASP.NET Core.

Кардинальные изменения

Используйте статьи в статье Критические изменения в .NET, чтобы найти критические изменения , которые могут применяться при обновлении приложения до более новой версии .NET.