В .NET 7 Preview 3 доступны обновления ASP.NET Core

от автора

Среди улучшений 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-профессию, актуальную в любое время:

Выбрать другую востребованную профессию.

Краткий каталог курсов и профессий


ссылка на оригинал статьи https://habr.com/ru/company/skillfactory/blog/661081/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *