Вышли Превью 6 и 7 .NET 11
Посмотрим на самые интересные новинки в ASP.NET Core.
1. Асинхронная проверка для минимальных API
Теперь минимальные API поддерживают асинхронные валидаторы. Самый простой способ добавить асинхронное правило — это пользовательский атрибут валидации. Наследуйте от AsyncValidationAttribute и реализуйте IsValidAsync, чтобы запрашивать БД или удаленный API без блокировки потока. Синхронный метод IsValid также является абстрактным; выбрасывайте исключение, если атрибут проверяется только асинхронно.
Для проверки, охватывающей несколько свойств или весь объект, реализуйте IAsyncValidatableObject и возвращайте результаты в виде IAsyncEnumerable<ValidationResult>. Поскольку IAsyncValidatableObject наследует IValidatableObject, также реализуйте синхронный метод Validate. Если тип проверяется только асинхронно, выбрасывайте исключение из Validate, чтобы его проверка не пропускалась молча синхронными API.
Валидаторы выполняются параллельно, где это возможно: асинхронные атрибуты одного и того же члена запускаются одновременно, элементы коллекции проверяются параллельно, и фреймворк сохраняет существующий порядок проверки: член, тип, IValidatableObject.
2. Автоматическая защита от межсайтовых запросов (CSRF)
Приложения, созданные с помощью WebApplication.CreateBuilder, теперь автоматически отклоняют небезопасные межсайтовые запросы на основе заголовков Sec-Fetch-Site и Origin браузера. Эта легковесная защита от CSRF включается без какой-либо настройки и применяется к минимальным API, MVC, Razor Pages и Blazor. Разрешаются запросы из одного источника, инициированные пользователем переходы и запросы от клиентов, не использующих браузер, в то время как межсайтовый запрос браузера, пытающийся обработать форму, отклоняется. Эту защиту можно использовать вместо или вместе с существующей системой защиты от подделки запросов на основе токенов. Поскольку она работает автоматически, проектам Blazor Web App больше не требуется вызывать
app.UseAntiforgery().Чтобы отключить защиту конечной точки, используйте метод
.DisableAntiforgery() (для минимальных API) или [IgnoreAntiforgeryToken] (для MVC); чтобы отключить эту функцию для всего приложения, установите ключ конфигурации DisableCsrfProtection. Для полного контроля над решением о доверии зарегистрируйте собственную реализацию ICsrfProtection.3. OpenAPI 3.2 по умолчанию
Сгенерированные документы OpenAPI теперь по умолчанию ориентированы на OpenAPI 3.2 – новейшую версию спецификации. Изменяется только версия по умолчанию; ваш код генерации и конфигурация остаются неизменными. Укажите версию OpenAPI явно, чтобы она была ориентирована на более раннюю версию для инструментов, которые ещё не используют 3.2.
4. Объединения в ASP.NET Core
Поскольку ASP.NET Core использует System.Text.Json для JSON, типы-объединения работают как тела JSON-запросов и возвращаемые типы без какой-либо специфической конфигурации:
- Минимальные API — параметры тела запроса и возвращаемые типы, включая Task<Union>, IAsyncEnumerable<Union> и Results<T1, T2>;
- MVC и Razor Pages — в телах JSON-запросов и ответах;
- SignalR — параметры методов хаба, возвращаемые значения и элементы потока при использовании протокола JSON Hub;
- Blazor — параметры компонентов, аргументы JavaScript-interop и результаты, а также сохраняемое состояния компонента.
Для OpenAPI конечная точка, возвращающая объединение, описывается схемой anyOf, в которой перечислены все типы вариантов. Сторонние генераторы, такие как Swashbuckle и NSwag, пока не распознают объединения и будут создавать свою схему по умолчанию.
В этом превью действуют некоторые ограничения. Поддерживаются только тела запросов и ответы в формате JSON. Привязка объединения к строке запроса, значениям маршрута, заголовкам или полям формы пока недоступна. Когда несколько вариантов сериализуются в один и тот же формат JSON, их можно различить с помощью классификатора
[JsonUnion] (из System.Text.Json). Объединения в SignalR требуют протокола JSON Hub; Протоколы MessagePack и Newtonsoft.Json не поддерживают объединения.5. Атрибут «прерыватель цепи» для конечных точек
Новый атрибут
[ShortCircuit] помечает конечную точку для запуска сразу после маршрутизации, пропуская остальную часть конвейера промежуточного ПО. Это атрибутная форма существующего соглашения о конечных точках ShortCircuit(), поэтому его можно применять непосредственно к контроллерам и действиям MVC. Это полезно для конечных точек, которым не требуется аутентификация, CORS или другое промежуточное ПО, например, health-check или ответ robots.txt. Это позволяет избежать затрат на запуск этого промежуточного ПО. Конечная точка по-прежнему запускается и выдаёт свой ответ; можно передать необязательный код состояния, например [ShortCircuit(404)].6. Встроенная локализация валидации
Microsoft.Extensions.Validation теперь локализует сообщения валидации и отображаемые имена. Пакет Microsoft.Extensions.Validation.Localization, доступный только в предварительной версии, и его API AddValidationLocalization<TResource>()/IValidationLocalizer удалены; локализация теперь активируется автоматически, как только регистрируется IStringLocalizerFactory, и поиск подходящей локализации инициируется генератором кода валидации в вашей сборке.
builder.Services.AddLocalization();
builder.Services.AddValidation();
…
[ValidatableType]
public class CustomerModel
{
// ключ ресурса для имени
[Display(Name = "CustomerName")]
// ключ ресурса для сообщения об ошибке
[Required(ErrorMessage = "NameRequired")]
public string? Name { get; set; }
}
Ключи определяются на основе собственных ресурсов модели, а в случае промаха используется встроенное сообщение атрибута. Атрибуты, которые уже локализуются (через
ErrorMessageResourceType или [Display(ResourceType = …)]), полностью обходят конвейер локализации валидации. Пользовательский атрибут, которому необходимо подставить свои значения в шаблон сообщения, может реализовать интерфейс IValidationMessageFormatter.К валидации минимальных API и Blazor применяются те же правила локализации, поэтому сообщение локализуется одинаково независимо от того, где используется модель.
Источники:
- https://github.com/dotnet/core/blob/main/release-notes/11.0/preview/preview6/aspnetcore.md
- https://github.com/dotnet/core/blob/main/release-notes/11.0/preview/preview7/aspnetcore.md
