Новые возможности ASP.NET Core 8.0

В этой статье описаны наиболее значительные изменения в ASP.NET Core 8.0 со ссылками на соответствующую документацию.

Blazor

Веб-интерфейс полного стека

С выпуском .NET 8 Blazor — это платформа веб-интерфейса полного стека для разработки приложений, которые отображают содержимое на уровне компонента или страницы:

  • Отрисовка статического сервера (также называемая отрисовкой на стороне статического сервера, статическим SSR) для создания статического HTML-кода на сервере.
  • Интерактивная отрисовка сервера (также называемая интерактивной отрисовкой на стороне сервера, интерактивной службой SSR) для создания интерактивных компонентов с предварительной отрисовкой на сервере.
  • Интерактивная отрисовка WebAssembly (также называемая отрисовкой на стороне клиента, CSR, которая всегда считается интерактивной) для создания интерактивных компонентов на клиенте с предварительной отрисовкой на сервере.
  • Интерактивная автоматическая отрисовка (автоматическая) для первоначального использования серверной ASP.NET Core для отрисовки содержимого и интерактивности. Среда выполнения .NET WebAssembly на клиенте используется для последующей отрисовки и взаимодействия после Blazor скачивания пакета и активации среды выполнения WebAssembly. Интерактивная автоматическая отрисовка обычно обеспечивает самый быстрый запуск приложения.

Режимы интерактивной отрисовки по умолчанию также предварительно отображают содержимое.

Дополнительные сведения см. в следующих статьях:

Примеры всей Blazor документации были обновлены для использования в Blazor веб-приложения. Blazor Server Примеры остаются в содержимом, версиях для .NET 7 или более ранних версий.

Новая статья о библиотеках классов со статическим отображением на стороне сервера (статический SSR)

Мы добавили новую статью, которая обсуждает авторство библиотек компонентов в Razor библиотеках классов (RCLs) со статическим отображением на стороне сервера (статический SSR).

Дополнительные сведения см. в статье ASP.NET Библиотеки классов Core Razor (RCLs) со статическим отображением на стороне сервера (статический SSR).

Новая статья о проблемах кэширования HTTP

Мы добавили новую статью, в которой рассматриваются некоторые распространенные проблемы с кэшированием HTTP, которые могут возникнуть при обновлении Blazor приложений в основных версиях и устранении проблем с кэшированием HTTP.

Дополнительные сведения см. в разделе "Избегание проблем с кэшированием HTTP" при обновлении приложений ASP.NET CoreBlazor.

Новый Blazor шаблон веб-приложения

Мы представили новый Blazor шаблон проекта: Blazor шаблон веб-приложения . Новый шаблон предоставляет единую отправную точку для использования Blazor компонентов для создания любого стиля веб-интерфейса. Шаблон объединяет сильные стороны существующих Blazor Server и Blazor WebAssembly размещенных моделей с новыми Blazor возможностями, добавленными в .NET 8: статическое отрисовка на стороне сервера (статический SSR), потоковая отрисовка, улучшенная навигация и обработка форм, а также возможность добавления интерактивности с помощью либо Blazor ServerBlazor WebAssembly на основе каждого компонента.

В рамках объединения различных Blazor моделей размещения в одну модель в .NET 8 мы также консолидируем количество Blazor шаблонов проектов. Мы удалили Blazor Server шаблон, и параметр ASP.NET Core Hosted был удален из Blazor WebAssembly шаблона. Оба этих сценария представлены параметрами при использовании Blazor шаблона веб-приложения.

Примечание.

Существующие Blazor Server и Blazor WebAssembly приложения остаются поддерживаемыми в .NET 8. При необходимости эти приложения можно обновить, чтобы использовать новые функции веб-интерфейса полнотековых веб-интерфейсов Blazor .

Дополнительные сведения о новом Blazor шаблоне веб-приложения см. в следующих статьях:

Новые JS инициализаторы для Blazor веб-приложения

Для Blazor Server, Blazor WebAssemblyи Blazor Hybrid приложений:

  • beforeStart используется для таких задач, как настройка процесса загрузки, уровня ведения журнала и других параметров.
  • afterStarted используется для таких задач, как регистрация Blazor прослушивателей событий и пользовательских типов событий.

Предыдущие устаревшие инициализаторы JS не вызываются по умолчанию в Blazor веб-приложении. Для Blazor веб-приложения используется новый набор инициализаторовJS: beforeWebStart, afterWebStarted, beforeServerStart, afterServerStartedbeforeWebAssemblyStartи afterWebAssemblyStarted.

Дополнительные сведения см. в статье Запуск ASP.NET Core Blazor.

Разделение рекомендаций по предварительной подготовке и интеграции

В предыдущих выпусках .NET мы рассмотрели предварительную и интеграцию в одной статье. Чтобы упростить и сосредоточиться на нашем охвате, мы разделили темы на следующие новые статьи, которые были обновлены для .NET 8:

Сохранение состояния компонента в Blazor веб-приложении

Состояние компонента можно сохранять и читать в Blazor веб-приложении с помощью существующей PersistentComponentState службы. Это полезно для сохранения состояния компонента во время предварительной подготовки.

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

Обработка форм и привязка модели

Blazor Теперь компоненты могут обрабатывать отправленные запросы формы, включая привязку модели и проверку данных запроса. Компоненты могут реализовывать формы с отдельными обработчиками форм с помощью стандартного HTML-тега <form> или использования существующего EditForm компонента.

Привязка модели формы учитывает Blazor атрибуты контракта данных (например, [DataMember] и [IgnoreDataMember]) для настройки привязки данных формы к модели.

Новая поддержка антифоргерии включена в .NET 8. Новый AntiforgeryToken компонент отображает маркер антифоргерии в виде скрытого поля, а новый [RequireAntiforgeryToken] атрибут обеспечивает защиту от антифоргерии. Если антифоргерия проверка завершается ошибкой, возвращается ответ 400 (недопустимый запрос) без обработки формы. Новые функции антифоргерии включены по умолчанию для форм на основе Editform форм и могут применяться вручную к стандартным HTML-формам.

Дополнительные сведения см. в разделе ASP.NET Общие сведения о формах CoreBlazor.

Улучшенная навигация и обработка форм

Отрисовка на стороне статического сервера (статический SSR) обычно выполняет полное обновление страницы при переходе пользователя на новую страницу или отправке формы. В .NET 8 можно улучшить навигацию по страницам и обработку форм, Blazor перехватив запрос и выполнив запрос на получение. Blazor затем обрабатывает содержимое отрисованного ответа, исправляя его в браузере DOM. Улучшенная навигация и обработка форм избегает необходимости полного обновления страницы и сохраняет больше состояния страницы, поэтому страницы загружаются быстрее и более гладко. Расширенная навигация включена по умолчанию при загрузке скрипта Blazor .blazor.web.js Улучшенная обработка форм может быть дополнительно включена для определенных форм.

Новый расширенный API навигации позволяет обновить текущую страницу путем вызова NavigationManager.Refresh(bool forceLoad = false).

Дополнительные сведения см. в следующих разделах Blazorстатьи о маршрутизации :

Новая статья о статической отрисовке с улучшенной навигацией для JS взаимодействия

Некоторые приложения зависят от JS взаимодействия для выполнения задач инициализации, относящихся к каждой странице. При использовании Blazorрасширенной функции навигации с статически отрисованными страницами, выполняющими JS задачи инициализации взаимодействия, некоторые JS страницы могут не выполняться повторно, как ожидалось при каждом возникновении расширенной навигации по страницам. В новой статье объясняется, как устранить этот сценарий в Blazor веб-приложения:

ASP.NET Core Blazor JavaScript со статическим отображением на стороне сервера (статический SSR)

Потоковая отрисовка

Теперь вы можете передавать обновления содержимого в поток ответа при использовании статической отрисовки на стороне сервера (статический SSR) с Blazor. Потоковая отрисовка может улучшить пользовательский интерфейс для страниц, выполняющих длительные асинхронные задачи, чтобы полностью отрисовывать содержимое, как только оно доступно.

Например, для отрисовки страницы может потребоваться выполнить длительный запрос базы данных или вызов API. Как правило, асинхронные задачи, выполняемые в рамках отрисовки страницы, должны завершиться до отправки отрисованного ответа, что может отложить загрузку страницы. Потоковая отрисовка изначально отображает всю страницу с содержимым заполнителя при выполнении асинхронных операций. После завершения асинхронных операций обновленное содержимое отправляется клиенту в том же подключении ответа и исправлено в DOM. Преимуществом этого подхода является то, что основной макет приложения отображается как можно быстрее и страница обновляется сразу после готовности содержимого.

Дополнительные сведения см. в статье Отрисовка компонентов Razor ASP.NET Core.

Внедрение ключевых служб в компоненты

Blazor теперь поддерживает внедрение ключевых служб с помощью атрибута [Inject] . Ключи позволяют определить регистрацию и потребление служб при использовании внедрения зависимостей. Используйте новое InjectAttribute.Key свойство, чтобы указать ключ для внедрения службы:

[Inject(Key = "my-service")]
public IMyService MyService { get; set; }

Директива @injectRazor не поддерживает ключевые службы для этого выпуска, но работа отслеживается обновлением @inject для поддержки ключевых служб (dotnet/razor #9286) для будущего выпуска .NET.

Дополнительные сведения см. в статье Внедрение зависимостей Blazor ASP.NET Core.

Доступ HttpContext как каскадный параметр

Теперь можно получить доступ к текущему HttpContext в качестве каскадного параметра из статического компонента сервера:

[CascadingParameter]
public HttpContext? HttpContext { get; set; }

HttpContext Доступ к компоненту статического сервера может быть полезен для проверки и изменения заголовков или других свойств.

Пример передачи HttpContext маркеров состояния, доступа и обновления компонентов см. в дополнительных сценариях безопасности на стороне сервера ASP.NET CoreBlazor.

Отрисовка Razor компонентов вне ASP.NET Core

Теперь вы можете отрисовки Razor компонентов вне контекста HTTP-запроса. Компоненты можно отрисовывать Razor как HTML непосредственно в строку или поток независимо от среды размещения ASP.NET Core. Это удобно для сценариев, в которых требуется создать фрагменты HTML, например для создания электронной почты или статического содержимого сайта.

Дополнительные сведения см. в разделе "Компоненты отрисовки Razor за пределами ASP.NET Core".

Поддержка разделов

Новые SectionOutlet и SectionContent компоненты в Blazor добавлении поддержки указания точек для содержимого, которое можно заполнить позже. Разделы часто используются для определения заполнителей в макетах, которые затем заполняются определенными страницами. Разделы ссылаются по уникальному имени или с помощью уникального идентификатора объекта.

Дополнительные сведения см. в разделах ASP.NET CoreBlazor.

Поддержка страницы ошибок

Blazorвеб-приложения может определить настраиваемую страницу ошибок для использования с по промежуточного слоя обработки исключений ASP.NET Core. Шаблон Blazor проекта веб-приложения включает страницу ошибок по умолчанию (Components/Pages/Error.razor) с аналогичным содержимым, используемым в приложениях MVC и Razor Pages. При отображении страницы ошибок в ответ на запрос из ПО промежуточного слоя обработки исключений страница ошибки всегда отображается как статический компонент сервера, даже если в противном случае включена интерактивность.

Error.razor в источнике ссылок 8.0

QuickGrid

Компонент Blazor QuickGrid больше не является экспериментальным и теперь является частью Blazor платформы в .NET 8.

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

Дополнительные сведения см. в разделе ASP.NET Компонент QuickGrid CoreBlazor.

Маршрут к именованным элементам

Blazor теперь поддерживается использование маршрутизации на стороне клиента для перехода к определенному элементу HTML на странице с использованием стандартных фрагментов URL-адресов. Если указать идентификатор html-элемента с помощью стандартного id атрибута, правильно прокручивается до этого элемента, Blazor когда фрагмент URL-адреса соответствует идентификатору элемента.

Дополнительные сведения см. в статье Маршрутизация ASP.NET Core Blazor и навигация.

Каскадные значения корневого уровня

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

Дополнительные сведения см. в статье Каскадные значения и параметры ASP.NET Core Blazor.

Виртуализация пустого содержимого

Используйте новый EmptyContent параметр компонента Virtualize для предоставления содержимого при загрузке компонента и Items пустой или ItemsProviderResult<T>.TotalItemCount нулевой.

Дополнительные сведения см. в статье Виртуализация компонентов Razor ASP.NET Core.

Закрытие каналов при отсутствии оставшихся интерактивных компонентов сервера

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

Мониторинг SignalR активности канала

Теперь вы можете отслеживать активность входящего канала в приложениях на стороне сервера с помощью нового CreateInboundActivityHandler метода CircuitHandler. Действие входящего канала — это любое действие, отправленное из браузера на сервер, например события пользовательского интерфейса или вызовы взаимодействия JavaScript-to-.NET.

Дополнительные сведения см. в статье Руководство по ASP.NET Core BlazorSignalR.

Более быстрая производительность среды выполнения с помощью Jiterpreter

Jiterpreter — это новая функция выполнения в .NET 8, которая обеспечивает поддержку частичной JIT-компиляции при запуске в WebAssembly для повышения производительности среды выполнения.

Дополнительные сведения см. в статье Размещение и развертывание ASP.NET Core Blazor WebAssembly.

Заранее (AOT) SIMD и обработка исключений

Blazor WebAssembly Перед компиляцией (AOT) теперь используется SIMD с фиксированной шириной WebAssembly и обработка исключений WebAssembly по умолчанию для повышения производительности среды выполнения.

Дополнительные сведения см. в следующих статьях:

Упаковка webcil для веб-приложений

Webcil — это удобная для интернета упаковка сборок .NET, которые удаляют содержимое, относящееся к собственному выполнению Windows, чтобы избежать проблем при развертывании в средах, которые блокируют загрузку или использование .dll файлов. Webcil включен по умолчанию для Blazor WebAssembly приложений.

Дополнительные сведения см. в статье Размещение и развертывание ASP.NET Core Blazor WebAssembly.

Примечание.

До выпуска .NET 8 руководство по макету развертывания для ASP.NET Основные размещенные Blazor WebAssembly приложения обращается к средам, которые блокируют загрузку и выполнение БИБЛИОТЕК DLL с помощью многопартийного подхода. В .NET 8 или более поздней версии Blazor используется формат файла Webcil для решения этой проблемы. Многопартийное объединение с помощью экспериментального пакета NuGet, описанного в статье макета развертывания WebAssembly, не поддерживается для Blazor приложений в .NET 8 или более поздней версии. Дополнительные сведения см. в статье "Улучшение Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle пакета", чтобы определить пользовательский формат пакета (dotnet/aspnetcore #36978). Если вы хотите продолжить использование пакета с несколькими частями в приложениях .NET 8 или более поздних версий, вы можете использовать инструкции в статье для создания собственного пакета NuGet с несколькими частями, но он не будет поддерживаться корпорацией Майкрософт.

Blazor WebAssembly улучшения отладки

При отладке .NET в WebAssembly отладчик теперь скачивает данные символов из расположений символов, настроенных в настройках Visual Studio. Это улучшает возможности отладки для приложений, использующих пакеты NuGet.

Теперь вы можете отлаживать Blazor WebAssembly приложения с помощью Firefox. Blazor WebAssembly Для отладки приложений требуется настройка браузера для удаленной отладки, а затем подключение к браузеру с помощью средств разработчика браузера с помощью прокси-сервера отладки .NET WebAssembly. Отладка Firefox из Visual Studio в настоящее время не поддерживается.

Дополнительные сведения см. в разделе Отладка приложений ASP.NET CoreBlazor.

Совместимость политики безопасности содержимого (CSP)

Blazor WebAssembly больше не требует включения источника скрипта unsafe-eval при указании политики безопасности содержимого (CSP).

Дополнительные сведения см. в разделе "Принудительное применение политики безопасности содержимого" для ASP.NET Core Blazor.

Обработка перехвата исключений за пределами жизненного Razor цикла компонента

Используйте ComponentBase.DispatchExceptionAsync компонент для Razor обработки исключений, возникающих за пределами стека вызовов жизненного цикла компонента. Это позволяет коду компонента обрабатывать исключения, как если бы они были исключениями метода жизненного цикла. После этого Blazorмеханизмы обработки ошибок, такие как границы ошибок, могут обрабатывать исключения.

Дополнительные сведения см. в статье Обработка ошибок в приложениях Blazor ASP.NET Core.

Настройка среды выполнения .NET WebAssembly

Среда выполнения .NET WebAssembly теперь может быть настроена для Blazor запуска.

Дополнительные сведения см. в статье Запуск ASP.NET Core Blazor.

Настройка времени ожидания подключения в HubConnectionBuilder

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

Дополнительные сведения см. в следующих разделах:

Шаблоны проектов пролили Открытый знак

Blazor Шаблоны проектов больше не зависят от открытых знаковых знаков для значков.

Поддержка отмены и закрытия диалоговых окон

Blazor теперь поддерживает cancel элементы HTML и close события dialog .

В следующем примере :

  • OnClose вызывается при закрытии диалогового my-dialog окна с помощью кнопки "Закрыть ".
  • OnCancel вызывается при отмене диалогового окна с помощью клавиши ESC . При закрытии диалогового окна HTML с помощью клавиши ESC активируются как события, так cancel и close события.
<div>
    <p>Output: @message</p>

    <button onclick="document.getElementById('my-dialog').showModal()">
        Show modal dialog
    </button>

    <dialog id="my-dialog" @onclose="OnClose" @oncancel="OnCancel">
        <p>Hi there!</p>

        <form method="dialog">
            <button>Close</button>
        </form>
    </dialog>
</div>

@code {
    private string? message;

    private void OnClose(EventArgs e) => message += "onclose, ";

    private void OnCancel(EventArgs e) => message += "oncancel, ";
}

BlazorIdentity Пользовательского интерфейса

Blazorподдерживает создание полного BlazorIdentity пользовательского интерфейса при выборе параметра проверки подлинности для отдельных учетных записей. Можно выбрать параметр для отдельных учетных записей в диалоговом окне нового проекта для Blazor веб-приложения из Visual Studio или передать -au|--auth параметр Individual из командной строки при создании нового проекта.

Дополнительные сведения см. на следующих ресурсах:

Защита Blazor WebAssembly с помощью ASP.NET Core Identity

В Blazor документации содержится новая статья и пример приложения для защиты автономного Blazor WebAssembly приложения с помощью ASP.NET Core Identity.

Дополнительные сведения см. на следующих ресурсах:

Blazor Server с маршрутизацией Yarp

Маршрутизация и глубокая привязка для Blazor Server работы с Yarp работает правильно в .NET 8.

Дополнительные сведения см. в разделе "Миграция с ASP.NET Core 7.0 на 8.0".

Blazor Hybrid

В следующих статьях описаны изменения в Blazor Hybrid .NET 8.

[Parameter] Атрибут больше не требуется при указании из строки запроса

Атрибут [Parameter] больше не требуется при предоставлении параметра из строки запроса:

- [Parameter]
  [SupplyParameterFromQuery]

SignalR

Новый подход к настройке интервала времени ожидания сервера и поддержания активности

ServerTimeout(по умолчанию: 30 секунд) и KeepAliveInterval (по умолчанию: 15 секунд) можно задать напрямую.HubConnectionBuilder

Предыдущий подход для клиентов JavaScript

В следующем примере показано назначение значений, которые являются двойными значениями по умолчанию в ASP.NET Core 7.0 или более ранней версии:

var connection = new signalR.HubConnectionBuilder()
  .withUrl("/chatHub")
  .build();

connection.serverTimeoutInMilliseconds = 60000;
connection.keepAliveIntervalInMilliseconds = 30000;

Новый подход для клиентов JavaScript

В следующем примере показан новый подход к назначению значений, которые являются двойными значениями по умолчанию в ASP.NET Core 8.0 или более поздней версии:

var connection = new signalR.HubConnectionBuilder()
  .withUrl("/chatHub")
  .withServerTimeout(60000)
  .withKeepAlive(30000)
  .build();

Предыдущий подход для клиента Blazor Server JavaScript приложения

В следующем примере показано назначение значений, которые являются двойными значениями по умолчанию в ASP.NET Core 7.0 или более ранней версии:

Blazor.start({
  configureSignalR: function (builder) {
    let c = builder.build();
    c.serverTimeoutInMilliseconds = 60000;
    c.keepAliveIntervalInMilliseconds = 30000;
    builder.build = () => {
      return c;
    };
  }
});

Новый подход для клиента JavaScript серверного Blazor приложения

В следующем примере показан новый подход для назначения значений, которые являются двойными значениями по умолчанию в ASP.NET Core 8.0 или более поздней версии для Blazor веб-приложения и Blazor Server.

Blazor Веб-приложение:

Blazor.start({
  circuit: {
    configureSignalR: function (builder) {
      builder.withServerTimeout(60000).withKeepAliveInterval(30000);
    }
  }
});

Blazor Server:

Blazor.start({
  configureSignalR: function (builder) {
    builder.withServerTimeout(60000).withKeepAliveInterval(30000);
  }
});

Предыдущий подход для клиентов .NET

В следующем примере показано назначение значений, которые являются двойными значениями по умолчанию в ASP.NET Core 7.0 или более ранней версии:

var builder = new HubConnectionBuilder()
    .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
    .Build();

builder.ServerTimeout = TimeSpan.FromSeconds(60);
builder.KeepAliveInterval = TimeSpan.FromSeconds(30);

builder.On<string, string>("ReceiveMessage", (user, message) => ...

await builder.StartAsync();

Новый подход для клиентов .NET

В следующем примере показан новый подход к назначению значений, которые являются двойными значениями по умолчанию в ASP.NET Core 8.0 или более поздней версии:

var builder = new HubConnectionBuilder()
    .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
    .WithServerTimeout(TimeSpan.FromSeconds(60))
    .WithKeepAliveInterval(TimeSpan.FromSeconds(30))
    .Build();

builder.On<string, string>("ReceiveMessage", (user, message) => ...

await builder.StartAsync();

SignalR повторное подключение с отслеживанием состояния

SignalR Повторное подключение с отслеживанием состояния уменьшает предполагаемое время простоя клиентов, имеющих временное отключение в сетевом подключении, например при переключении сетевых подключений или временной потере доступа.

Повторное подключение с отслеживанием состояния достигается следующим образом:

  • Временно буферизация данных на сервере и клиенте.
  • Подтверждение полученных сообщений (ACK-ing) как сервером, так и клиентом.
  • Распознавая, когда подключение возвращается и повторяет сообщения, которые могли быть отправлены во время отключения подключения.

Повторное подключение с отслеживанием состояния доступно в ASP.NET Core 8.0 и более поздних версий.

Войдите на повторное подключение с отслеживанием состояния как в конечной точке концентратора сервера, так и в клиенте:

  • Обновите конфигурацию конечной точки концентратора сервера, чтобы включить AllowStatefulReconnects этот параметр:

    app.MapHub<MyHub>("/hubName", options =>
    {
        options.AllowStatefulReconnects = true;
    });
    

    При необходимости максимальный размер буфера в байтах, разрешенных сервером, можно задать глобально или для определенного концентратора с параметром StatefulReconnectBufferSize :

    Глобальный StatefulReconnectBufferSize набор параметров:

    builder.AddSignalR(o => o.StatefulReconnectBufferSize = 1000);
    

    Набор StatefulReconnectBufferSize параметров для определенного концентратора:

    builder.AddSignalR().AddHubOptions<MyHub>(o => o.StatefulReconnectBufferSize = 1000);
    

    Этот StatefulReconnectBufferSize параметр является необязательным с значением по умолчанию 100 000 байт.

  • Обновите клиентский withStatefulReconnect код JavaScript или TypeScript, чтобы включить этот параметр:

    const builder = new signalR.HubConnectionBuilder()
      .withUrl("/hubname")
      .withStatefulReconnect({ bufferSize: 1000 });  // Optional, defaults to 100,000
    const connection = builder.build();
    

    Этот bufferSize параметр является необязательным с значением по умолчанию 100 000 байт.

  • Обновите клиентский WithStatefulReconnect код .NET, чтобы включить этот параметр:

      var builder = new HubConnectionBuilder()
          .WithUrl("<hub url>")
          .WithStatefulReconnect();
      builder.Services.Configure<HubConnectionOptions>(o => o.StatefulReconnectBufferSize = 1000);
      var hubConnection = builder.Build();
    

    Этот StatefulReconnectBufferSize параметр является необязательным с значением по умолчанию 100 000 байт.

Дополнительные сведения см. в разделе "Настройка повторного подключения с отслеживанием состояния".

Минимальные API

В этом разделе описываются новые функции для минимальных API. Дополнительные сведения, относящиеся к минимальным API, см. в разделе "Собственный AOT ".

Язык и региональные параметры переопределения пользователей

Начиная с ASP.NET Core 8.0, свойство RequestLocalizationOptions.CultureInfoUseUserOverride позволяет приложению решить, следует ли использовать параметры Windows без дефекации для CultureInfoDateTimeFormat и NumberFormat свойств. Это не влияет на Linux. Это напрямую UseUserOverrideсоответствует .

    app.UseRequestLocalization(options =>
    {
        options.CultureInfoUseUserOverride = false;
    });

Привязка к формам

Явная привязка к значениям формы с помощью атрибута [FromForm] теперь поддерживается. Параметры, привязанные к запросу, [FromForm] включают маркер защиты от подделки. Маркер защиты от подделки проверяется при обработке запроса.

Выводимые привязки к формам с помощью IFormCollection, IFormFileа IFormFileCollection также типы поддерживаются. Метаданные OpenAPI выводятся для параметров формы для поддержки интеграции с пользовательским интерфейсом Swagger.

Дополнительные сведения см. в разделе:

Привязка из форм теперь поддерживается для:

  • Коллекции, например list and Dictionary
  • Сложные типы, например Todo или Project

Дополнительные сведения см. в разделе "Привязка к коллекциям и сложным типам из форм".

Антифоргерия с минимальными API

В этом выпуске добавляется ПО промежуточного слоя для проверки маркеров защиты от подделки, которые используются для устранения межсайтовых атак. Вызовите AddAntiforgery для регистрации служб антифоргерии в DI. WebApplicationBuilder автоматически добавляет ПО промежуточного слоя при регистрации служб защиты от подделки в контейнере DI. Маркеры антифоргерии используются для устранения атак на подделку межсайтовых запросов.

var builder = WebApplication.CreateBuilder();

builder.Services.AddAntiforgery();

var app = builder.Build();

app.UseAntiforgery();

app.MapGet("/", () => "Hello World!");

app.Run();

По промежуточному слоям защиты:

Маркер антифоргерии проверяется только в том случае, если:

  • Конечная точка содержит метаданные, реализующие IAntiforgeryMetadataRequiresValidation=true.
  • Метод HTTP, связанный с конечной точкой, является соответствующим методом HTTP. Соответствующие методы — это все методы HTTP, кроме TRACE, OPTIONS, HEAD и GET.
  • Запрос связан с допустимой конечной точкой.

Дополнительные сведения см. в разделе "Антифоргерия с минимальными API".

Новый IResettable интерфейс в ObjectPool

Microsoft.Extensions.ObjectPool обеспечивает поддержку экземпляров объектов в пуле в памяти. Приложения могут использовать пул объектов, если значения являются дорогостоящими для выделения или инициализации.

В этом выпуске мы упрощали использование пула IResettable объектов путем добавления интерфейса. Часто повторно используемые типы необходимо сбросить в состояние по умолчанию между использованием. IResettable типы автоматически сбрасываются при возвращении в пул объектов.

Дополнительные сведения см. в примере ObjectPool.

Собственный AOT

Добавлена поддержка .NET native перед временем (AOT). Приложения, опубликованные с помощью AOT, могут существенно повысить производительность: меньший размер приложения, меньшее использование памяти и ускорить запуск. Собственный AOT в настоящее время поддерживается gRPC, минимальным API и рабочими приложениями службы. Дополнительные сведения см. в разделе ASP.NET Core support for Native AOT and Tutorial: Publish an ASP.NET Core app using Native AOT. Сведения о известных проблемах с совместимостью ASP.NET Core и Native AOT см. в статье GitHub issue dotnet/core #8288.

Библиотеки и собственный AOT

Многие популярные библиотеки, используемые в проектах ASP.NET Core, в настоящее время имеют некоторые проблемы совместимости при использовании в проекте, предназначенных для собственного AOT, например:

  • Использование отражения для проверки и обнаружения типов.
  • Условное загрузка библиотек во время выполнения.
  • Создание кода на лету для реализации функциональных возможностей.

Библиотеки, использующие эти динамические функции, необходимо обновить для работы с машинным AOT. Их можно обновить с помощью таких средств, как генераторы источников Roslyn.

Авторы библиотеки, надеясь поддержать Собственный AOT, рекомендуется:

Шаблон нового проекта

Новый шаблон проекта ASP.NET Core Web API (native AOT) (короткое имяwebapiaot) создает проект с включенной публикацией AOT. Дополнительные сведения см . в шаблоне Веб-API (Native AOT).

Новый CreateSlimBuilder метод

Метод, CreateSlimBuilder() используемый в шаблоне веб-API (Native AOT), инициализирует WebApplicationBuilder минимальные функции ASP.NET Core, необходимые для запуска приложения. Этот CreateSlimBuilder метод включает следующие функции, которые обычно необходимы для эффективной разработки.

  • JSКонфигурация ФАЙЛА ON для appsettings.json и appsettings.{EnvironmentName}.json.
  • Конфигурация секретов пользователей.
  • Ведение журнала консоли.
  • Конфигурация ведения журнала.

Дополнительные сведения см. в разделе " CreateSlimBuilder Метод".

Новый CreateEmptyBuilder метод

Существует еще один новый WebApplicationBuilder метод фабрики для создания небольших приложений, которые содержат только необходимые функции: WebApplication.CreateEmptyBuilder(WebApplicationOptions options) Это WebApplicationBuilder создается без встроенного поведения. Приложение, которое он создает, содержит только службы и ПО промежуточного слоя, которые явно настроены.

Ниже приведен пример использования этого API для создания небольшого веб-приложения:

var builder = WebApplication.CreateEmptyBuilder(new WebApplicationOptions());
builder.WebHost.UseKestrelCore();

var app = builder.Build();

app.Use(async (context, next) =>
{
    await context.Response.WriteAsync("Hello, World!");
    await next(context);
});

Console.WriteLine("Running...");
app.Run();

Публикация этого кода с помощью собственного AOT с помощью .NET 8 Preview 7 на компьютере linux-x64 приводит к автономному собственному исполняемому файлу около 8,5 МБ.

Уменьшение размера приложения с помощью настраиваемой поддержки HTTPS

Мы еще больше сократили размер двоичного файла AOT для приложений, которые не нуждаются в поддержке HTTPS или HTTP/3. Не используется протокол HTTPS или HTTP/3 для приложений, работающих за прокси-сервером завершения TLS (например, размещенным в Azure). Новый WebApplication.CreateSlimBuilder метод исключает эту функцию по умолчанию. Его можно добавить, вызвав builder.WebHost.UseKestrelHttpsConfiguration() HTTPS или builder.WebHost.UseQuic() http/3. Дополнительные сведения см. в разделе " CreateSlimBuilder Метод".

JSСериализация on для созданных компилятором IAsyncEnumerable<T> типов

Добавлены новые функции для System.Text.Json повышения поддержки машинного AOT. Эти новые функции добавляют возможности для режима System.Text.Jsonсоздания источника, так как отражение не поддерживается AOT.

Одним из новых функций является поддержка JSсериализации реализаций IAsyncEnumerable<T> ON, реализованных компилятором C#. Эта поддержка открывает свое использование в проектах ASP.NET Core, настроенных для публикации Native AOT.

Этот API полезен в сценариях, когда обработчик маршрутов используется yield return для асинхронного возврата перечисления. Например, для материализации строк из запроса базы данных. Дополнительные сведения см. в разделе о поддержке типов unspeakable в объявлении .NET 8 (предварительная версия 4).

Сведения о других улучшениях в создании источника см. в System.Text.Json статье об улучшениях сериализации в .NET 8.

API верхнего уровня, аннотированные для предупреждений об обрезки

Основные точки входа в подсистемы, которые не работают надежно с Native AOT, теперь помечены. Если эти методы вызываются из приложения с поддержкой Машинного AOT, предоставляется предупреждение. Например, следующий код выдает предупреждение при вызове AddControllers , так как этот API не является обрезкой и не поддерживается машинным AOT.

Окно Visual Studio с предупреждением IL2026 в методе AddControllers, в котором говорится, что MVC в настоящее время не поддерживает собственный AOT.

Генератор делегатов запросов

Чтобы обеспечить минимальную совместимость API с машинным AOT, мы представляем генератор делегатов запросов (RDG). RDG — это генератор источника, который делает то, что RequestDelegateFactory делает RDF. То есть он превращает различные MapGet()MapPost()вызовы и вызывает их в RequestDelegate экземпляры, связанные с указанными маршрутами. Но вместо того, чтобы выполнять его в памяти в приложении при запуске, RDG выполняет его во время компиляции и создает код C# непосредственно в проекте. The RDG:

  • Удаляет поколение среды выполнения этого кода.
  • Гарантирует, что типы, используемые в API, статически перенализуются цепочкой инструментов AOT native AOT.
  • Гарантирует, что обязательный код не обрезается.

Мы работаем над тем, чтобы максимально возможное количество функций API поддерживается RDG и, таким образом, совместимо с собственным AOT.

RDG включен автоматически в проекте при публикации с помощью Собственного AOT. RDG можно включить вручную, даже если не использовать собственный AOT, задав <EnableRequestDelegateGenerator>true</EnableRequestDelegateGenerator> файл проекта. Это может быть полезно при первоначальной оценке готовности проекта к собственному AOT или уменьшению времени запуска приложения.

Улучшенная производительность с помощью перехватчиков

Генератор делегатов запросов использует новую функцию компилятора перехватчиков C# 12 для поддержки перехвата вызовов к минимальным методам сопоставления API со статически созданными вариантами во время выполнения. Использование перехватчиков приводит к увеличению производительности запуска для приложений, скомпилированных с PublishAot.

Ведение журнала и обработка исключений во время компиляции, созданные минимальными API

Минимальные API, созданные во время выполнения, поддерживают автоматическое ведение журнала (или исключение в средах разработки) при сбое привязки параметров. .NET 8 предоставляет ту же поддержку API, созданных во время компиляции с помощью генератора делегатов запросов (RDG). Дополнительные сведения см. в разделе "Ведение журнала и обработка исключений" во время компиляции, созданных минимальными API.

AOT и System.Text.Json

Минимальные API оптимизированы для получения и возврата JSполезных данных ON, System.Text.Jsonпоэтому требования к совместимости для JSON и Native AOT также применяются. Для обеспечения совместимости собственного AOT требуется использование исходного генератора System.Text.Json . Все типы, принятые в качестве параметров для делегатов запросов или возвращаемые из делегатов запросов в минимальных API, должны быть настроены для JsonSerializerContext зарегистрированного с помощью внедрения зависимостей ASP.NET Core, например:

// Register the JSON serializer context with DI
builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});

...

// Add types used in the minimal API app to source generated JSON serializer content
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{

}

Дополнительные сведения об TypeInfoResolverChain API см. в следующих ресурсах:

Библиотеки и собственный AOT

Многие распространенные библиотеки, доступные для проектов ASP.NET Core, сегодня имеют некоторые проблемы совместимости, если они используются в проекте, ориентированном на собственный AOT. Популярные библиотеки часто используют динамические возможности отражения .NET для проверки и обнаружения типов, условной загрузки библиотек во время выполнения и создания кода на лету для реализации их функций. Эти библиотеки необходимо обновить для работы с Native AOT с помощью таких средств, как генераторы источников Roslyn.

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

Kestrel и серверы HTTP.sys

Существует несколько новых возможностей для Kestrel HTTP.sys.

Поддержка именованных каналов в Kestrel

Именованные каналы — это популярная технология для создания взаимодействия между процессами (IPC) между приложениями Windows. Теперь можно создать сервер IPC с помощью .NET Kestrelи именованных каналов.

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenNamedPipe("MyPipeName");
});

Дополнительные сведения об этой функции и использовании .NET и gRPC для создания сервера и клиента IPC см. в разделе межпроцессное взаимодействие с gRPC.

Улучшения производительности для транспорта именованных каналов

Мы улучшили производительность подключения именованных каналов. KestrelТеперь транспорт именованных каналов принимает подключения параллельно и повторно использует NamedPipeServerStream экземпляры.

Время создания 100 000 подключений:

  • До : 5,916 секунды
  • После : 2,374 секунды

Поддержка HTTP/2 по протоколу TLS (HTTPS) в macOS Kestrel

.NET 8 добавляет поддержку согласования протокола уровня приложений (ALPN) в macOS. ALPN — это функция TLS, используемая для согласования протокола HTTP, используемого подключением. Например, ALPN позволяет браузерам и другим http-клиентам запрашивать подключение HTTP/2. Эта функция особенно полезна для приложений gRPC, требующих HTTP/2. Дополнительные сведения см. в разделе "Использование HTTP/2" с веб-сервером ASP.NET CoreKestrel.

Просмотр файла сертификата в Kestrel

Сертификаты TLS, настроенные по пути, теперь отслеживаются при передаче KestrelServerOptions.Configure()измененийreloadOnChange. Изменение файла сертификата обрабатывается так же, как изменение настроенного пути (т. е. перезагрузка конечных точек).

Обратите внимание, что удаление файлов специально не отслеживается, так как они возникают временно и завершаются сбоем сервера, если они не временные.

Предупреждение, когда указанные протоколы HTTP не будут использоваться

Если протокол TLS отключен и http/1.x доступен, http/2 и HTTP/3 будут отключены, даже если они были указаны. Это может вызвать некоторые неприятные сюрпризы, поэтому мы добавили выходные данные предупреждения, чтобы сообщить вам, когда это произойдет.

HTTP_PORTSключи конфигурации и HTTPS_PORTS

Приложения и контейнеры часто получают порт для прослушивания, например 80, без дополнительных ограничений, таких как узел или путь. HTTP_PORTS и HTTPS_PORTS являются новыми ключами конфигурации, которые позволяют указывать порты прослушивания для Kestrel серверов и HTTP.sys серверов. Их можно определить с DOTNET_ASPNETCORE_ префиксами или переменными среды или напрямую с помощью любых других входных данных конфигурации, таких как appsettings.json. Каждый из них — это список значений портов с запятой. Например:

ASPNETCORE_HTTP_PORTS=80;8080
ASPNETCORE_HTTPS_PORTS=443;8081

Это сокращено для следующего вида, указывающее схему (HTTP или HTTPS) и любой узел или IP-адрес:

ASPNETCORE_URLS=http://*:80/;http://*:8080/;https://*:443/;https://*:8081/

Дополнительные сведения см. в разделе "Настройка конечных точек" для веб-сервера ASP.NET Core Kestrel и реализации веб-сервера HTTP.sys в ASP.NET Core.

Имя узла SNI в ITlsHandshakeFeature

Имя узла "Указание имени сервера" (SNI) теперь предоставляется в свойстве ITlsHandshakeFeature HostName интерфейса.

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

Обычно имя узла обрабатывается только в стеке TLS и используется для выбора соответствующего сертификата. Но, предоставляя его, другие компоненты в приложении могут использовать эти сведения для таких целей, как диагностика, ограничение скорости, маршрутизация и выставление счетов.

Предоставление имени узла полезно для крупномасштабных служб, управляющих тысячами привязок SNI. Эта функция может значительно повысить эффективность отладки во время эскалации клиентов. Повышенная прозрачность позволяет быстрее решать проблемы и повысить надежность службы.

Дополнительные сведения см. в разделе ITlsHandshakeFeature.HostName.

IHttpSysRequestTimingFeature

IHttpSysRequestTimingFeature предоставляет подробные сведения о времени для запросов при использовании сервера HTTP.sys и внутрипроцессного размещения с iis:

  • Метки времени получаются с помощью QueryPerformanceCounter.
  • Частоту метки времени можно получить с помощью QueryPerformanceFrequency.
  • Индекс времени можно привести к HttpSysRequestTimingType , чтобы узнать, какое время представляет.
  • Значение может быть равно 0, если время недоступно для текущего запроса.

IHttpSysRequestTimingFeature.TryGetTimestamp извлекает метку времени для предоставленного типа времени:

using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();

    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    var timingType = HttpSysRequestTimingType.RequestRoutingEnd;

    if (feature.TryGetTimestamp(timingType, out var timestamp))
    {
        logger.LogInformation("Timestamp {timingType}: {timestamp}",
                                          timingType, timestamp);
    }
    else
    {
        logger.LogInformation("Timestamp {timingType}: not available for the "
                                           + "current request",    timingType);
    }

    return next(context);
});

app.MapGet("/", () => Results.Ok());

app.Run();

Дополнительные сведения см. в разделе "Получение подробных сведений о времени" с помощью IHttpSysRequestTimingFeature и сведений о времени и в процессе размещения с помощью IIS.

HTTP.sys: поддержка буферизации ответов в режиме ядра

В некоторых сценариях большие объемы небольших операций записи с высокой задержкой могут привести к значительному влиянию HTTP.sysна производительность. Это влияние связано с отсутствием буфера Pipe в HTTP.sys реализации. Для повышения производительности в этих сценариях добавлена HTTP.sysподдержка буферизации ответов. Включите буферизацию, задав значение HttpSysOptions.EnableKernelResponseBufferingtrue.

Буферизация ответов должна быть включена приложением, выполняющим синхронные операции ввода-вывода или асинхронные операции ввода-вывода без одной выдающейся записи за раз. В этих сценариях буферизация ответов может значительно повысить пропускную способность по сравнению с подключениями с высокой задержкой.

Приложения, использующие асинхронные операции ввода-вывода и которые могут иметь несколько невыполненных операций записи за раз, не должны использовать этот флаг. Включение этого флага может привести к повышению использования ЦП и памяти http.Sys.

Проверка подлинности и авторизация

ASP.NET Core 8 добавляет новые функции для проверки подлинности и авторизации.

Identity Конечные точки API

MapIdentityApi<TUser> — это новый метод расширения, который добавляет две конечные точки API (/register и /login). Основная цель MapIdentityApi заключается в том, чтобы разработчики легко использовали ASP.NET Core Identity для проверки подлинности в одностраничных приложениях javaScript или Blazor приложениях. Вместо использования пользовательского интерфейса по умолчанию, предоставленного ASP.NET Core Identity, который основан на Razor страницах, Api mapIdentityдобавляет JSконечные точки ON API, которые более подходят для приложений SPA и небрежемерных приложений. Дополнительные сведения см. в разделе Identity конечных точек API.

IAuthorizationRequirementData

До ASP.NET Core 8 добавьте параметризованную политику авторизации в конечную точку, необходимую для реализации:

  • AuthorizeAttribute для каждой политики.
  • AuthorizationPolicyProvider для обработки настраиваемой политики из контракта на основе строк.
  • AuthorizationRequirement для политики.
  • AuthorizationHandler для каждого требования.

Например, рассмотрим следующий пример, написанный для ASP.NET Core 7.0:

using AuthRequirementsData.Authorization;
using Microsoft.AspNetCore.Authorization;

var builder = WebApplication.CreateBuilder();

builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();
builder.Services.AddControllers();
builder.Services.AddSingleton<IAuthorizationPolicyProvider, MinimumAgePolicyProvider>();
builder.Services.AddSingleton<IAuthorizationHandler, MinimumAgeAuthorizationHandler>();

var app = builder.Build();

app.MapControllers();

app.Run();
using Microsoft.AspNetCore.Mvc;

namespace AuthRequirementsData.Controllers;

[ApiController]
[Route("api/[controller]")]
public class GreetingsController : Controller
{
    [MinimumAgeAuthorize(16)]
    [HttpGet("hello")]
    public string Hello() => $"Hello {(HttpContext.User.Identity?.Name ?? "world")}!";
}
using Microsoft.AspNetCore.Authorization;
using System.Globalization;
using System.Security.Claims;

namespace AuthRequirementsData.Authorization;

class MinimumAgeAuthorizationHandler : AuthorizationHandler<MinimumAgeRequirement>
{
    private readonly ILogger<MinimumAgeAuthorizationHandler> _logger;

    public MinimumAgeAuthorizationHandler(ILogger<MinimumAgeAuthorizationHandler> logger)
    {
        _logger = logger;
    }

    // Check whether a given MinimumAgeRequirement is satisfied or not for a particular
    // context.
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                               MinimumAgeRequirement requirement)
    {
        // Log as a warning so that it's very clear in sample output which authorization
        // policies(and requirements/handlers) are in use.
        _logger.LogWarning("Evaluating authorization requirement for age >= {age}",
                                                                    requirement.Age);

        // Check the user's age
        var dateOfBirthClaim = context.User.FindFirst(c => c.Type ==
                                                                 ClaimTypes.DateOfBirth);
        if (dateOfBirthClaim != null)
        {
            // If the user has a date of birth claim, check their age
            var dateOfBirth = Convert.ToDateTime(dateOfBirthClaim.Value, CultureInfo.InvariantCulture);
            var age = DateTime.Now.Year - dateOfBirth.Year;
            if (dateOfBirth > DateTime.Now.AddYears(-age))
            {
                // Adjust age if the user hasn't had a birthday yet this year.
                age--;
            }

            // If the user meets the age criterion, mark the authorization requirement
            // succeeded.
            if (age >= requirement.Age)
            {
                _logger.LogInformation("Minimum age authorization requirement {age} satisfied",
                                         requirement.Age);
                context.Succeed(requirement);
            }
            else
            {
                _logger.LogInformation("Current user's DateOfBirth claim ({dateOfBirth})" +
                    " does not satisfy the minimum age authorization requirement {age}",
                    dateOfBirthClaim.Value,
                    requirement.Age);
            }
        }
        else
        {
            _logger.LogInformation("No DateOfBirth claim present");
        }

        return Task.CompletedTask;
    }
}

Полный пример приведен врепозитории AspNetCore.Docs.Samples .

ASP.NET Core 8 представляет IAuthorizationRequirementData интерфейс. Интерфейс IAuthorizationRequirementData позволяет определению атрибута указывать требования, связанные с политикой авторизации. Используя IAuthorizationRequirementDataпредыдущий код пользовательской политики авторизации, можно записать с меньшим количеством строк кода. Обновленный Program.cs файл:

  using AuthRequirementsData.Authorization;
  using Microsoft.AspNetCore.Authorization;
  
  var builder = WebApplication.CreateBuilder();
  
  builder.Services.AddAuthentication().AddJwtBearer();
  builder.Services.AddAuthorization();
  builder.Services.AddControllers();
- builder.Services.AddSingleton<IAuthorizationPolicyProvider, MinimumAgePolicyProvider>();
  builder.Services.AddSingleton<IAuthorizationHandler, MinimumAgeAuthorizationHandler>();
  
  var app = builder.Build();
  
  app.MapControllers();
  
  app.Run();

Обновлено MinimumAgeAuthorizationHandler:

using Microsoft.AspNetCore.Authorization;
using System.Globalization;
using System.Security.Claims;

namespace AuthRequirementsData.Authorization;

- class MinimumAgeAuthorizationHandler : AuthorizationHandler<MinimumAgeRequirement>
+ class MinimumAgeAuthorizationHandler : AuthorizationHandler<MinimumAgeAuthorizeAttribute>
{
    private readonly ILogger<MinimumAgeAuthorizationHandler> _logger;

    public MinimumAgeAuthorizationHandler(ILogger<MinimumAgeAuthorizationHandler> logger)
    {
        _logger = logger;
    }

    // Check whether a given MinimumAgeRequirement is satisfied or not for a particular
    // context
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
-                                              MinimumAgeRequirement requirement)
+                                              MinimumAgeAuthorizeAttribute requirement)
    {
        // Remaining code omitted for brevity.

Полный обновленный пример можно найти здесь.

Подробный анализ нового примера см . в настраиваемых политиках авторизации с помощью IAuthorizationRequirementData .

Защита конечных точек пользовательского интерфейса Swagger

Конечные точки пользовательского интерфейса Swagger теперь можно защитить в рабочих средах путем вызова MapSwagger().RequireAuthorization. Дополнительные сведения см. в разделе "Защита конечных точек пользовательского интерфейса Swagger"

Разное

В следующих разделах описаны другие функции в ASP.NET Core 8.

Поддержка ключевых служб в внедрении зависимостей

Ключи служб относятся к механизму регистрации и получения служб внедрения зависимостей (DI) с помощью ключей. Служба связана с ключом путем вызова AddKeyedSingleton (или AddKeyedScopedAddKeyedTransient) для регистрации. Доступ к зарегистрированной службе путем указания ключа с атрибутом [FromKeyedServices] . В следующем коде показано, как использовать ключи служб:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddKeyedSingleton<ICache, BigCache>("big");
builder.Services.AddKeyedSingleton<ICache, SmallCache>("small");
builder.Services.AddControllers();

var app = builder.Build();

app.MapGet("/big", ([FromKeyedServices("big")] ICache bigCache) => bigCache.Get("date"));
app.MapGet("/small", ([FromKeyedServices("small")] ICache smallCache) =>
                                                               smallCache.Get("date"));

app.MapControllers();

app.Run();

public interface ICache
{
    object Get(string key);
}
public class BigCache : ICache
{
    public object Get(string key) => $"Resolving {key} from big cache.";
}

public class SmallCache : ICache
{
    public object Get(string key) => $"Resolving {key} from small cache.";
}

[ApiController]
[Route("/cache")]
public class CustomServicesApiController : Controller
{
    [HttpGet("big-cache")]
    public ActionResult<object> GetOk([FromKeyedServices("big")] ICache cache)
    {
        return cache.Get("data-mvc");
    }
}

public class MyHub : Hub
{
    public void Method([FromKeyedServices("small")] ICache cache)
    {
        Console.WriteLine(cache.Get("signalr"));
    }
}

Шаблоны проектов Visual Studio для приложений SPA с серверной частью ASP.NET Core

Шаблоны проектов Visual Studio теперь являются рекомендуемым способом создания одностраничных приложений (SPAs), имеющих серверную часть ASP.NET Core. Шаблоны предоставляются для создания приложений на основе платформ JavaScript Angular, React и Vue. Эти шаблоны:

  • Создайте решение Visual Studio с интерфейсным проектом и серверным проектом.
  • Используйте тип проекта Visual Studio для JavaScript и TypeScript (esproj) для внешнего интерфейса.
  • Используйте проект ASP.NET Core для серверной части.

Дополнительные сведения о шаблонах Visual Studio и о том, как получить доступ к устаревшим шаблонам, см. в разделе "Обзор приложений с одной страницей" (SPAs) в ASP.NET Core

Поддержка универсальных атрибутов

Атрибуты, необходимые ранее параметру Type , теперь доступны в более чистых универсальных вариантах. Это возможно благодаря поддержке универсальных атрибутов в C# 11. Например, синтаксис для аннотирования типа ответа действия можно изменить следующим образом:

[ApiController]
[Route("api/[controller]")]
public class TodosController : Controller
{
  [HttpGet("/")]
- [ProducesResponseType(typeof(Todo), StatusCodes.Status200OK)]
+ [ProducesResponseType<Todo>(StatusCodes.Status200OK)]
  public Todo Get() => new Todo(1, "Write a sample", DateTime.Now, false);
}

Универсальные варианты поддерживаются для следующих атрибутов:

  • [ProducesResponseType<T>]
  • [Produces<T>]
  • [MiddlewareFilter<T>]
  • [ModelBinder<T>]
  • [ModelMetadataType<T>]
  • [ServiceFilter<T>]
  • [TypeFilter<T>]

Анализ кода в приложениях ASP.NET Core

Новые анализаторы, показанные в следующей таблице, доступны в ASP.NET Core 8.0.

ИД диагностики Критическое или некритическое Description
ASP0016 Некритическое Не возвращайте значение из RequestDelegate
ASP0019 Некритическое Рекомендуем использовать IHeaderDictionary.Append или индексатор
ASP0020 Некритическое Сложные типы, на которые ссылаются параметры маршрута, должны быть синтаксический анализ
ASP0021 Некритическое Возвращаемый тип метода BindAsync должен быть ValueTask<T>
ASP0022 Некритическое Конфликт маршрутов, обнаруженный между обработчиками маршрутов
ASP0023 Некритическое MVC: конфликт маршрутов, обнаруженный между обработчиками маршрутов
ASP0024 Некритическое Обработчик маршрутов имеет несколько параметров с атрибутом [FromBody]
ASP0025 Некритическое Использование AddAuthorizationBuilder

Средство маршрутизации

ASP.NET Core основан на маршрутизации. Минимальные API, веб-API, Razor страницы и Blazor все маршруты используются для настройки сопоставления HTTP-запросов с кодом.

В .NET 8 мы инвестировали в набор новых функций, чтобы упростить маршрутизацию для обучения и использования. К этим новым функциям относятся:

Дополнительные сведения см. в разделе "Средства маршрутизации" в .NET 8.

ASP.NET Основные метрики

Метрики — это измерения, сообщаемые с течением времени, и чаще всего используются для мониторинга работоспособности приложения и создания оповещений. Например, счетчик, который сообщает о неудачных HTTP-запросах, может отображаться на панелях мониторинга или создавать оповещения, когда сбои передают пороговое значение.

Эта предварительная версия добавляет новые метрики в ASP.NET Core с помощью System.Diagnostics.Metrics. Metrics — это современный API для создания отчетов и сбора сведений о приложениях.

Метрики предлагают множество улучшений по сравнению с существующими счетчиками событий:

  • Новые виды измерений с счетчиками, датчиками и гистограммами.
  • Мощные отчеты с многомерными значениями.
  • Интеграция с более широкой облачной экосистемой путем соответствия стандартам OpenTelemetry.

Метрики добавлены для размещения ASP.NET Core и KestrelSignalR. Дополнительные сведения см. в разделе System.Diagnostics.Metrics.

IExceptionHandler

IExceptionHandler — это новый интерфейс, который дает разработчику обратный вызов для обработки известных исключений в центральном расположении.

IExceptionHandler реализации регистрируются путем вызова IServiceCollection.AddExceptionHandler<T>. Можно добавить несколько реализаций, и они вызываются в порядке регистрации. Если обработчик исключений обрабатывает запрос, он может вернуться true к остановке обработки. Если исключение не обрабатывается обработчиком исключений, то элемент управления возвращается к поведению по умолчанию и параметрам из по промежуточного слоя.

Дополнительные сведения см. в разделе IExceptionHandler.

Улучшенный интерфейс отладки

Атрибуты настройки отладки добавлены в такие типы, как HttpContext, HttpRequest, , HttpResponseClaimsPrincipalи WebApplication. Расширенный отладчик для этих типов упрощает поиск важных сведений в отладчике интегрированной среды разработки. На следующих снимках экрана показано, что эти атрибуты отображаются в отображении HttpContextотладчика.

.NET 7:

Отображение отладчика httpContext в .NET 7 без использования.

.NET 8:

Полезное отображение типа HttpContext в .NET 8.

Отладчик отображает WebApplication важные сведения, такие как настроенные конечные точки, ПО промежуточного слоя и IConfiguration значения.

.NET 7:

Отображение отладчика webApplication типа WebApplication в .NET 7.

.NET 8:

Полезное отображение отладчика типа WebApplication в .NET 8.

Дополнительные сведения об улучшениях отладки в .NET 8 см. в следующем разделе:

IPNetwork.Parse и TryParse.

Новые Parse и методы IPNetwork для добавления поддержки создания IPNetwork с помощью входной строки в нотации CIDR или "нотации TryParse косой черты".

Ниже приведены примеры IPv4:

// Using Parse
var network = IPNetwork.Parse("192.168.0.1/32");
// Using TryParse
bool success = IPNetwork.TryParse("192.168.0.1/32", out var network);
// Constructor equivalent
var network = new IPNetwork(IPAddress.Parse("192.168.0.1"), 32);

Ниже приведены примеры для IPv6:

// Using Parse
var network = IPNetwork.Parse("2001:db8:3c4d::1/128");
// Using TryParse
bool success = IPNetwork.TryParse("2001:db8:3c4d::1/128", out var network);
// Constructor equivalent
var network = new IPNetwork(IPAddress.Parse("2001:db8:3c4d::1"), 128);

Кэширование выходных данных на основе Redis

ASP.NET Core 8 добавляет поддержку использования Redis в качестве распределенного кэша для кэширования выходных данных. Кэширование выходных данных — это функция, которая позволяет приложению кэшировать выходные данные минимальной конечной точки API, действия контроллера или Razor страницы. Дополнительные сведения см. в разделе "Кэширование выходных данных".

По промежуточному слоям короткого канала после маршрутизации

При маршрутизации соответствует конечной точке, обычно он позволяет выполнять остальную часть конвейера по промежуточного слоя перед вызовом логики конечной точки. Службы могут снизить использование ресурсов, отфильтровав известные запросы на ранних этапах конвейера. ShortCircuit Используйте метод расширения, чтобы вызвать маршрутизацию, чтобы немедленно вызвать логику конечной точки, а затем завершить запрос. Например, определенному маршруту может не потребоваться пройти проверку подлинности или ПО промежуточного слоя CORS. В следующем примере запросы на короткие каналы, соответствующие маршруту /short-circuit :

app.MapGet("/short-circuit", () => "Short circuiting!").ShortCircuit();

MapShortCircuit Используйте метод для настройки короткого канала для нескольких маршрутов одновременно, передав в него массив префиксов URL-адресов. Например, браузеры и боты часто пробуют серверы для известных путей, таких как robots.txt и favicon.ico. Если у приложения нет этих файлов, одна строка кода может настроить оба маршрута:

app.MapShortCircuit(404, "robots.txt", "favicon.ico");

Дополнительные сведения см. в разделе ПО промежуточного слоя короткого канала после маршрутизации.

Расширяемость ПО промежуточного слоя ведения журнала HTTP

ПО промежуточного слоя ведения журнала HTTP имеет несколько новых возможностей:

  • HttpLoggingFields.Duration: при включении ПО промежуточного слоя выдает новый журнал в конце запроса и ответа, который измеряет общее время обработки. Это новое поле добавлено в HttpLoggingFields.All набор.
  • HttpLoggingOptions.CombineLogs: при включении ПО промежуточного слоя объединяет все включенные журналы для запроса и ответа в один журнал в конце. Одно сообщение журнала включает в себя запрос, текст запроса, ответ, текст ответа и длительность.
  • IHttpLoggingInterceptor: новый интерфейс для службы, которая может быть реализована и зарегистрирована (с помощью AddHttpLoggingInterceptor) для получения обратных вызовов для каждого запроса и ответа для настройки сведений, которые регистрируются в журнале. Все параметры журнала, относящиеся к конечной точке, применяются сначала и затем можно переопределить в этих обратных вызовах. Реализация может:
    • Проверьте запрос и ответ.
    • Включите или отключите любой HttpLoggingFields.
    • Измените объем регистра запроса или ответа.
    • Добавьте настраиваемые поля в журналы.

Дополнительные сведения см. в разделе "Ведение журнала HTTP" в .NET Core и ASP.NET Core.

Новые API в ProblemDetails для поддержки более устойчивых интеграции

В .NET 7 служба ProblemDetails была введена для улучшения возможностей создания ответов на ошибки, соответствующих спецификации ProblemDetails. В .NET 8 был добавлен новый API, чтобы упростить реализацию резервного поведения, если IProblemDetailsService не удается создать ProblemDetails. В следующем примере показано использование нового TryWriteAsync API:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();

var app = builder.Build();

app.UseExceptionHandler(exceptionHandlerApp =>
{
    exceptionHandlerApp.Run(async httpContext =>
    {
        var pds = httpContext.RequestServices.GetService<IProblemDetailsService>();
        if (pds == null
            || !await pds.TryWriteAsync(new() { HttpContext = httpContext }))
        {
            // Fallback behavior
            await httpContext.Response.WriteAsync("Fallback: An error occurred.");
        }
    });
});

app.MapGet("/exception", () =>
{
    throw new InvalidOperationException("Sample Exception");
});

app.MapGet("/", () => "Test by calling /exception");

app.Run();

Дополнительные сведения см. в резервном резерве IProblemDetailsService

Дополнительные ресурсы