
Среди улучшений ASP.NET Core поддержка фильтров обработчиков маршрутов Minimal API, повышение тестируемости обработчиков маршрутов Minimal API, биндинг в контроллерах MVC и контроллерах API с помощью TryParse и не только. Материалом из блога разработчиков делимся к старту курса по разработке на C#.
Чтобы больше узнать о работе над ASP.NET Core для .NET 7, смотрите план развития ASP.NET Core для .NET 7 на GitHub.
Начнём
Загрузить SDK .NET 7 можно здесь.
Если вы на Windows и работаете с Visual Studio, мы рекомендуем установить последнюю предварительную версию Visual Studio 2022. На Visual Studio версии для Mac поддержки .NET 7 Preview 3 пока нет, но скоро она появится.
Чтобы установить последние инструменты сборки .NET WebAssembly, выполните эту команду с повышенными привилегиями:
dotnet workload install wasm-tools
Cоздание проектов .NET 6 Blazor с помощью SDK .NET 7 и инструментов сборки .NET 7 WebAssembly пока не поддерживается. Мы исправим это в обновлении .NET 7.
Обновление существующего проекта
Чтобы обновить существующее приложение ASP.NET Core с .NET 7 Preview 2 до .NET 7 Preview 3, измените:
-
все ссылки на пакеты Microsoft.AspNetCore.* — до версии 7.0.0-preview.3.*;
-
все ссылки на пакеты Microsoft.Extensions.* — до версии 7.0.0-preview.3.*;
Список изменений, ломающих обратную совместимость, смотрите по ссылке.
Поддержка фильтров обработчиков маршрутов в Minimal API
Теперь в обработчиках маршрутов приложений Minimal поддерживаются фильтры, выполняются они перед выполнением основной логики обработчика маршрута. Эти фильтры можно использовать, чтобы проверить и изменить обработчик, а также перехватить его выполнение. Регистрируются эти фильтры по-разному. К примеру, через RouteHandlerFilterDelegate и метод расширения AddFilter:
app.MapGet("/hello/{name}", (string name) => $"Hello, {name}!") .AddFilter((context, next) => { var name = (string) context.Parameters[0]; if (name == "Bob") { return Result.Problem("No Bob's allowed"); } return next(context); });
Или с помощью стратегии фабрики фильтров, которая открывает доступ к RouteHandlerContext. Последний, в свою очередь, предоставляет доступ к связанному с обработчиком MethodInfo, а также к метаданным, зарегистрированным в конечной точке:
app.MapGet("/hello/{name}", (string name) => $"Hello, {name}!") .AddFilter((routeHandlerContext, next) => { var parameters = routeHandlerContext.GetParameters(); var hasCorrectSignature = parameters.Length == 1 && parameters[0].GetType() == typeof(string); return (context) => { if (hasCorrectSignature) { var name = (string) context.Parameters[0]; if (name == "Bob") { return Result.Problem("No Bob's allowed"); } } return next(context); } });
Фильтры могут реализовывать интерфейс IRouteHandlerFilter, разрешаться из инъекции зависимостей или передаваться в качестве экземпляра:
app.MapGet("/hello/{name}", (string name) => $"Hello, {name}!") .AddFilter<MyFilter>();
Повышена тестируемость обработчиков маршрутов Minimal API
Типы реализации IResult с суффиксом HttpResult (OkObjectHttpResult, ProblemHttpResult и так далее) теперь открыты в пространстве имён Microsoft.AspNetCore.Http. Благодаря этим типам проще тестировать обработчики маршрутов Minimal API, вместо лямбда-выражений используя именованные методы:
[Fact] public async Task GetTodoReturnsTodoFromDatabase() { var todo = new Todo { Id = 42, Name = "Improve Results testability!" }; var mockDb = new MockTodoDb(new[] { todo }); var result = (OkObjectHttpResult)await TodoEndpoints.GetTodo(mockDb, todo.Id); //Assert Assert.Equal(200, result.StatusCode); var foundTodo = Assert.IsAssignableFrom<Models.Todo>(result.Value); Assert.Equal(id, foundTodo.Id); } [Fact] public void CreateTodoWithValidationProblems() { //Arrange var newTodo = default(Todo); var mockDb = new MockTodoDb(); //Act var result = TodoEndpoints.CreateTodo(mockDb, newTodo); //Assert var problemResult = Assert.IsAssignableFrom<ProblemHttpResult>(result); Assert.NotNull(problemResult.ProblemDetails); Assert.Equal(400, problemResult.StatusCode); }
Биндинг с помощью TryParse в контроллерах MVC и контроллерах API
Значения параметров действия контроллера теперь можно привязывать с помощью метода TryParse с одной из этих сигнатур:
public static bool TryParse(string value, T out result); public static bool TryParse(string value, IFormatProvider provider, T out result);
Ниже действие Get привязывает данные из строки запроса через метод типа-параметра TryParse:
public class TryParseController : ControllerBase { // GET /tryparse?data=MyName [HttpGet] public ActionResult Get([FromQuery]CustomTryParseObject data) => Ok(); public class CustomTryParseObject { public string? Name { get; set; } public static bool TryParse(string s, out CustomTryParseObject result) { if (s is null) { result = default; return false; } result = new CustomTryParseObject { Name = s }; return true; } } }
Новые перегрузки Results.Stream()
Для ситуаций, когда к базовому потоку ответов HTTP нужен доступ без буферизации, написаны новые перегрузки Results.Stream(…). Эти перегрузки упрощают передачу данных в поток ответов HTTP через API, например из хранилища BLOB-объектов Azure. Ниже Results.Stream() используется в обработке изображений через сервис ImageSharp:
app.MapGet("/process-image", async (HttpContext http) => { using var image = await Image.LoadAsync("puppy.jpeg"); int width = image.Width / 2; int height = image.Height / 2; image.Mutate(x => x.Resize(width, height)); http.Response.Headers.CacheControl = $"public,max-age={FromHours(24).TotalSeconds}"; return Results.Stream(stream => image.SaveAsync(stream, PngFormat.Instance), "image/png"); });
Повышена производительность соединения HTTP/2 с несколькими стримами
Мы изменили код записи фреймов HTTP/2. Этот код повышает производительность при наличии нескольких стримов, пытающихся записать данные в одном соединении HTTP/2. Теперь работа TLS отправляется в пул потоков.
Блокировка записи, которую другие стримы могут получить для записи своих данных, освобождается быстрее. Когда за эту блокировку есть конкуренция, сокращение времени ожидания может значительно повысить производительность.
Тест gRPC с 70 потоками в одном соединении с TLS показал увеличение количества запросов в секунду примерно на 15%.
Новое событие измерения времени запуска приложения — ServerReady
Если для измерений или диагностики вы используете EventSource и хотите измерить время запуска своего приложения, можно использовать новое событие ServerReady в источнике Microsoft.AspNetCore.Hosting. Это событие представляет момент, когда сервер запущен и работает.
Тёмная тема страницы исключений для разработчиков
Страница исключений для разработчиков ASP.NET Core теперь поддерживает тёмную тему:

За это улучшение благодарим @poke!
Обратная связь
Надеемся, что вам понравится этот предварительный релиз ASP.NET Core в .NET 7. Сообщите нам, что вы думаете об этих улучшениях, отправив Issues на GitHub. Спасибо, что попробовали ASP.NET Core!
А мы поможем прокачать скиллы или с самого начала освоить IT-профессию, актуальную в любое время:
Выбрать другую востребованную профессию.

Краткий каталог курсов и профессий
Data Science и Machine Learning
Python, веб-разработка
Мобильная разработка
Java и C#
От основ — в глубину
А также
ссылка на оригинал статьи https://habr.com/ru/company/skillfactory/blog/661081/
Добавить комментарий