Posted on 17. November 2023

Announcing ASP.NET Core in .NET 8

Анонс ASP.NET Core в .NET 8


ASP.NET Core у .NET 8 — це комплексне рішення для сучасної веброзробки. Він задовольняє всі ваші потреби в веброзробці від фронтенду до бекенду. За допомогою Blazor, а також високопродуктивних внутрішніх API, і сервісів, які є надійними і безпечними, ви можете створювати красиві, насичені та інтерактивні вебдодатки.  ASP.NET Core у .NET 8 ідеально підходить для створення хмарних додатків, а чудові інструменти у Visual Studio та Visual Studio Code підвищують вашу продуктивність. Завдяки ASP.NET Core у .NET 8 кожен розробник є розробником повного стека!


.NET 8 тепер доступний – оновіть свої проєкти ASP.NET Core сьогодні!

Починаймо

Щоб розпочати роботу з ASP.NET Core у .NET 8, інсталюйте .NET 8 SDK . .NET 8 також входить до складу Visual Studio 2022 і підтримується у Visual Studio Code з C# Dev Kit.


Якщо ви новачок у ASP.NET Core, ви можете розпочати навчання, перейшовши на https://asp.net і ознайомившись із можливостями ASP.NET Core.

Що нового?

Давайте розглянемо деякі чудові нові функції та вдосконалення, доступні в ASP.NET Core у .NET 8.


Продуктивність

ASP.NET Core у .NET 8 — це найшвидший реліз! Порівняно з .NET 7, ASP.NET Core у .NET 8 на 18% швидший за тестом Techempower JSON і на 24% швидший за тестом Fortunes:

Порівняння тестів Techempower .NET 7 і .NET 8

Ви можете прочитати все про покращення продуктивності ASP.NET Core у публікації блогу Бреннана Конроя « Покращення продуктивності в ASP.NET Core 8» .


Підтримка ASP.NET Core для нативного AOT

У .NET 8 ми представляємо власну підтримку AOT для ASP.NET Core, спочатку зосереджуючись на хмарних додатках API. Тепер можна опублікувати програму ASP.NET Core із власним AOT , створюючи автономну програму, яка завчасно (AOT) скомпільована до власного коду.

 

Власні програми AOT можуть мати менший розмір розгортання, запускатися дуже швидко та використовувати менше пам’яті. Програму можна запускати на машині, на якій не встановлено середовище виконання .NET. Перевага власного AOT є найбільш важливою для робочих навантажень із багатьма розгорнутими екземплярами, як-от хмарна інфраструктура та гіпермасштабовані служби.

Переваги використання нативного AOT з ASP.NET Core

Публікація та розгортання нативної програми AOT може надати такі переваги:

–  Зменшений розмір диска: під час публікації з використанням власного AOT створюється єдиний виконуваний файл, який містить програму разом із підмножиною коду із зовнішніх залежностей, які використовує програма. 

Зменшення розміру виконуваного файлу може призвести до:

- Менші образи контейнерів, наприклад, у сценаріях розгортання в контейнерах.

- Зменшення часу розгортання через менші образи.


Скорочений час запуску: нативні програми AOT можуть запускатися швидше, частково завдяки видаленню компіляції JIT. Скорочений запуск означає:

- Додаток готовий швидше обслуговувати запити.

- Покращене розгортання за допомогою оркестраторів контейнерів, які керують переходами від однієї версії програми до іншої.

– Зменшена потреба в пам’яті: програми ASP.NET Core, опубліковані як нативні AOT, можуть мати зменшені вимоги до пам’яті залежно від виконуваної роботи, оскільки вони ввімкнули новий режим DATAS GC за замовчуванням. Зменшення споживання пам’яті може призвести до більшої щільності розгортання та покращеної масштабованості.

Як приклад, ми запустили просту програму ASP.NET Core API у нашій лабораторії порівняльного аналізу, щоб порівняти відмінності в розмірі програми, використанні пам’яті, часу запуску та навантаженні ЦП, опублікованому з власним AOT і без нього:

Вид публікації

Час запуску (мс)

Розмір програми (МБ)

Робочий набір (Мб)

За замовчуванням

156

92.6

96

Нативний АОТ

48

10,0

41

Наведена вище таблиця показує, що публікація програми як нативної AOT значно покращує час запуску, розмір програми та використання пам’яті. Час запуску скорочено на 70%, розмір програми – на 89%, а використання пам’яті під навантаженням – на 57%!

Більш складний зразок програми API із методами CRUD-стилю, включаючи перевірку моделі, OpenAPI, автентифікацію JWT і авторизацію на основі політики, прив’язку конфігурації та присутність у базі даних PostgreSQL за допомогою Npgsql , вказує такі зміни в своїх показниках порівняно з нативним AOT:

Вид публікації

Час запуску (мс)

Розмір програми (МБ)

Робочий набір (Мб)

За замовчуванням

473

98,27

193

Нативний АОТ

115

21.55

121

Для цієї складнішої програми час запуску скорочено на 76%, розмір програми зменшено на 78%, а використання пам’яті під навантаженням – на 37% !

Ви можете досліджувати ці та інші показники на нашій загальнодоступній інформаційній панелі тестів.


Сумісність ASP.NET Core та нативної AOT

Не всі функції в ASP.NET Core сумісні з нативним AOT. Подібним чином не всі бібліотеки, які зазвичай використовуються в ASP.NET Core, сумісні з нативним AOT. .NET 8 є початком роботи над реалізацією нативного AOT в ASP.NET Core, з початковим фокусом на підтримку додатків, що використовують мінімальні API або gRPC і розгортаються в хмарних середовищах. Нагадуємо, що в .NET 7 з’явилася підтримка нативної публікації AOT для консольних проєктів. Ваші відгуки допоможуть скерувати наші зусилля для майбутніх випусків, щоб переконатися, що ми зосереджуємось на тих місцях, де переваги нативної AOT можуть мати найбільший вплив.


Нативні додатки AOT постачаються з кількома основними вимогами сумісності. До ключових належать:

– Без динамічного завантаження (наприклад, Assembly.LoadFile)

– Немає генерації коду виконання через JIT (наприклад, System.Reflection.Emit)

– Немає C++/CLI

– Немає вбудованого COM (стосується лише Windows)

– Потрібна обрізка, яка має обмеження

– Передбачає компіляцію в один файл, який має відомі несумісності

– Програми включають необхідні бібліотеки часу виконання (як самодостатні програми, збільшуючи їх розмір порівняно з програмами, що залежать від фреймворку)


Використання цих функцій, швидше за все, зробить програму несумісною з нативним AOT. Щоб допомогти перевірити, чи програма сумісна з AOT, інструменти видаватимуть попередження , коли виявлять використання несумісних функцій. Якщо використання міститься у вихідному коді самої програми, ці попередження відображатимуться як діагностика в редакторі та під час компіляції. Якщо використання відбувається в залежності (наприклад, пакет NuGet), попередження з’являться під час публікації, коли IL цілої програми буде скомпільовано до рідного коду.


У випадках, коли потрібна додаткова інформація, щоб визначити, чи функція використовується у спосіб, сумісний із рідною AOT, розробники можуть анотувати свій код інструкційними атрибутами, наприклад,  [DynamicallyAccessedMembers] щоб вказати, що учасники мають динамічний доступ і їх слід залишити необрізаними.


У деяких випадках функціональні можливості в програмах або бібліотеках потрібно буде повторно реалізувати, щоб вони були сумісні з нативним AOT. Типовим прикладом цього є використання рефлексії для генерації коду під час виконання. Генератори вихідного коду Roslyn дозволяють генерувати код під час компіляції з такими ж можливостями виявлення та перевірки типу, як і відображення на основі часу виконання, і є корисною альтернативою під час підготовки до сумісності з нативним AOT.


У наведеній нижче таблиці підсумовано сумісність функцій ASP.NET Core із нативним AOT:

Особливість

Повністю підтримується

Частково підтримується

Не підтримується

gRPC

Повністю підтримується



Мінімум API


Частково підтримується


MVC



Не підтримується

Blazor



Не підтримується

SignalR



Не підтримується

Автентифікація JWT

Повністю підтримується



Інша автентифікація



Не підтримується

CORS

Повністю підтримується



Перевірки стану здоров’я

Повністю підтримується



Протоколювання Http

Повністю підтримується



Локалізація

Повністю підтримується



Кешування виводу

Повністю підтримується



Обмеження швидкості

Повністю підтримується



Запит на декомпресію

Повністю підтримується



Кешування відповідей

Повністю підтримується



Стиснення відповіді

Повністю підтримується



Перепишіть

Повністю підтримується



Сесія



Не підтримується

SPA



Не підтримується

Статичні файли

Повністю підтримується



WebSockets

Повністю підтримується



 

Ви можете переглянути поточні відомі проблеми щодо сумісності ASP.NET Core та рідної AOT у .NET 8 тут.


Під час створення програми зверніть увагу на попередження AOT . Коректна робота програми, яка видає попередження AOT під час публікації, не гарантується. Якщо ви не отримуєте жодних попереджень AOT під час публікації, ви повинні бути впевнені, що ваша програма працюватиме стабільно після публікації для AOT, як це було під час робочого процесу розробки F5 / dotnet run. Однак, все одно важливо ретельно перевірити свою програму під час переходу на власну модель розгортання AOT, щоб переконатися, що функціональні можливості, спостережувані під час розробки (коли програму не обрізано та скомпільовано за допомогою JIT), збережені у власному виконуваному файлі.


Мінімальні API та нативний AOT

Щоб зробити мінімальні API сумісними з нативним AOT, ми запровадили Генератор делегатів запитів (RDG) . RDG — це генератор вихідних кодів , який виконує роботу, подібну до RequestDelegateFactory(RDF) , перетворюючи різноманітні виклики MapGet(), MapPost()тощо у вашій програмі на RequestDelegate, пов’язані з указаними маршрутами, але замість того, щоб робити це в пам’яті вашої програми під час її запуску, він робить це під час компіляції та генерує код C# безпосередньо у вашому проєкті. Це видаляє генерацію цього коду під час виконання та гарантує, що типи, які використовуються у ваших API, зберігаються в коді вашої програми таким чином, що його можна статично проаналізувати власним ланцюжком інструментів AOT, гарантуючи, що необхідний код не буде обрізано. Ми працювали над тим, щоб більшість функцій Minimal API, якими ви сьогодні користуєтеся, підтримувалися RDG і, отже, сумісні з нативним AOT.

RDG автоматично вмикається у вашому проєкті, коли ви вмикаєте публікацію за допомогою нативного AOT. Ви також можете вручну ввімкнути RDG, навіть якщо не використовуєте нативний AOT, вказавши 

у файлі проєкту.

Це може бути корисно під час початкової оцінки готовності вашого проєкту до нативної AOT або потенційно для скорочення часу запуску вашої програми.

 

Мінімальні API оптимізовано для отримання та повернення корисних даних JSON за допомогою System.Text.Json, тому також застосовуються вимоги сумісності для JSON і рідного AOT. Це вимагає використання  System.Text.Json source generator . Усі типи, які приймаються як параметри для делегатів запитів або повертаються від делегатів запитів у ваших мінімальних API, мають бути налаштовані на JsonSerializerContext зареєстрованому за допомогою ін’єкції залежностей ASP.NET Core, наприклад:

gRPC і нативний AOT

gRPC підтримує нативний AOT у .NET 8. Нативний AOT дозволяє публікувати клієнтські та серверні програми gRPC у вигляді невеликих швидких власних виконуваних файлів. Дізнайтеся більше про gRPC і нативний AOT у відповідних документах.


Бібліотеки та нативний АОТ

Багато поширених бібліотек, які ви любите використовувати у своїх проєктах ASP.NET Core сьогодні, матимуть певні проблеми сумісності під час використання в проєкті, націленому на власний AOT. Популярні бібліотеки часто покладаються на динамічні можливості відображення .NET для перевірки та виявлення типів, умовного завантаження бібліотек під час виконання та генерування коду на льоту для реалізації їх функціональних можливостей. Як було сказано раніше, така поведінка може спричинити проблеми сумісності з власним AOT, тому ці бібліотеки потрібно буде оновити, щоб працювати з власним AOT за допомогою таких інструментів, як генератори джерел Roslyn .

 

Авторам бібліотек, які бажають дізнатися більше про підготовку своїх бібліотек до нативного AOT, рекомендується почати з підготовки своєї бібліотеки до скорочення та дізнатися більше про ввімкнення аналізаторів AOT-сумісності у своїх бібліотечних проєктах.

Початок роботи з нативним розгортанням AOT в ASP.NET Core

Нативний AOT є опцією публікації. Компіляція AOT відбувається під час публікації програми. Проект, який використовує власну публікацію AOT, використовуватиме JIT-компіляцію під час налагодження або запуску як частини внутрішнього циклу розробника, але є деякі помітні відмінності:

– Деякі функції, несумісні з нативним AOT, вимкнено та створюють винятки під час виконання.

– Аналізатор вихідного коду ввімкнено, щоб виділяти код проєкту, який несумісний із нативним AOT. Під час публікації вся програма, включаючи пакети NuGet, на які посилаються, знову аналізується на сумісність.


Власний аналіз AOT під час публікації включає весь код програми та бібліотеки, від яких залежить програма. Перегляньте нативні попередження AOT і вживіть заходів для виправлення. Радимо часто тестувати програми перед публікацією, щоб виявляти проблеми на ранніх етапах життєвого циклу розробки.

Перш ніж публікувати проєкти .NET із власним AOT, потрібно встановити такі передумови.


На Windows інсталюйте Visual Studio 2022 і включіть робоче навантаження «Розробка робочого столу за допомогою C++» з усіма компонентами за замовчуванням.

Знімок екрана робочого навантаження «Розробка робочого столу за допомогою C++» у програмі встановлення Visual Studio 2022

У Linux інсталюйте інструментарій компілятора та пакети розробника для бібліотек, від яких залежить середовище виконання .NET:

 

– Ubuntu (18.04+)

– Alpine (3.15+)

Зауважте, що наразі кросплатформна власна публікація AOT не підтримується, тобто вам потрібно виконати публікацію на тому самому типі платформи, що й передбачувана ціль, наприклад, якщо розгортання націлено на Linux, виконайте публікацію на Linux. Контейнери Docker можуть бути зручним способом увімкнення кросплатформної публікації, приклад чого можна знайти в репозиторії dotnet-docker .


Власні програми AOT, опубліковані ASP.NET Core, можна розгортати та запускати будь-де, де можуть власні виконувані файли. Для цього популярним вибором є контейнери. Власні програми AOT, опубліковані .NET, мають ті самі вимоги до платформи, що й автономні програми .NET, і тому mcr.microsoft.com/dotnet/runtime-depsїх слід використовувати як базовий образ.


Нативні готові для AOT шаблони проєктів

Шаблони для створення проектів ASP.NET Core із нативним AOT у Visual Studio

У .NET 8 є два власних шаблони проєктів із підтримкою AOT, які допоможуть вам почати створювати програми ASP.NET Core за допомогою власного AOT.

Шаблон проєкту «ASP.NET Core gRPC Service» оновлено, щоб включити нову опцію «Увімкнути власну публікацію AOT», яка, коли вибрано, налаштовує новий проект для публікації як власної AOT. Це робиться шляхом налаштування true у файлі .csproj проєкту.


Існує також абсолютно новий шаблон проєкту «ASP.NET Core Web API (native AOT)», який створює проєкт, більш безпосередньо зосереджений на сценаріях, налаштованих на хмару, перш за все API. Цей шаблон попередньо налаштовано для власного AOT і відрізняється від наявного шаблону проєкту «Web API» таким чином:


– Використовує лише мінімальні API, оскільки MVC ще не сумісний з AOT

– Використовує нове API WebApplication.CreateSlimBuilder, щоб гарантувати, що за замовчуванням увімкнено лише основні функції, мінімізуючи розмір розгорнутої програми

– Налаштовано лише для прослуховування HTTP, оскільки трафік HTTPS зазвичай обробляється вхідною службою в хмарних розгортаннях

– Не включає профіль запуску для роботи під IIS або IIS Express

– Вмикає генератор джерела серіалізатора JSON

– Включає зразок «Todos API» замість зразка прогнозу погоди


Ви можете створити новий проєкт Web API, налаштований на публікацію як нативний AOT, використовуючи dotnet CLI:

Ось вміст Program.cs у проєкті, створеному за допомогою нового шаблону «ASP.NET Core Web API (native AOT)»:

Нативний заклик до дії AOT

Власне розгортання AOT підходить не для всіх програм, але в сценаріях, коли переваги, які пропонує нативний AOT, є переконливими, воно може мати величезний вплив. Хоча це лише початок, ми хотіли б, щоб ви спробували власну підтримку AOT для ASP.NET Core у .NET 8 і поділіться будь-яким відгуком, залишивши коментар тут або зареєструвавши проблему на GitHub . Обов’язково прочитайте поточні відомі проблеми щодо сумісності ASP.NET Core і рідної AOT.

У .NET 8 разом із функціями ASP.NET Core, описаними тут, автентифікацією JWT, перевіркою параметрів і доступом до даних ADO.NET для SQLite та PostgreSQL, усе було оновлено для сумісності з рідною AOT. Ми з нетерпінням чекаємо, що екосистема .NET продовжить використовувати більше бібліотек і функцій для нативного AOT.

Повний стек UI з Blazor

Blazor у .NET 8 перетворився з переконливої ​​клієнтської веб-платформи інтерфейсу користувача на повну структуру веб-інтерфейсу користувача, яка може виконувати всі ваші потреби веб-інтерфейсу користувача. Blazor у .NET 8 поєднує в собі сильні сторони Blazor WebAssembly, Blazor Server і вдосконалених методів рендерингу на стороні сервера в одній компонентній структурі. Використовуючи як клієнт, так і сервер, Blazor дає змогу створити оптимізований веб-інтерфейс, який сподобається вашим користувачам.

Blazor у .NET 8 тепер підтримує такі нові можливості:

Статична візуалізація на стороні сервера: розміщуйте компоненти Blazor як кінцеві точки ASP.NET Core, які рендерять статичний HTML у відповідь на запити, щоб вміст рендерився негайно без необхідності завантажувати будь-який клієнтський код. Також обробляйте запити форм за допомогою вбудованих компонентів форми Blazor і зручної моделі програмування на основі подій.

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

Потокове відтворення: миттєво відтворюйте компоненти, щоб швидко отримати пікселі на екрані, поки виконуються довготривалі асинхронні завдання, а потім автоматично передавайте оновлення в браузер, коли вміст стає доступним.

Увімкнути інтерактивність для кожного компонента або сторінки: увімкніть інтерактивне відтворення на основі Blazor Server або Blazor WebAssembly для окремих компонентів або сторінок за допомогою нової директиви Razor – @rendermode. Ви платите лише за інтерактивність, як-от встановлення з’єднання WebSocket або завантаження середовища виконання .NET WebAssembly, де воно використовується.

Автоматичний вибір режиму візуалізації під час виконання: автоматично перемикайте користувачів із сервера на клієнт під час виконання, щоб покращити час завантаження програми та масштабованість. Компонент спочатку рендериться в інтерактивному режимі за допомогою Blazor Server, тоді як середовище виконання .NET WebAssembly завантажується у фоновому режимі. Під час майбутніх візитів компонент автоматично перемикається на використання Blazor WebAssembly, щоб отримати швидкий час початкового завантаження та менше навантаження на сервери.


Більше вбудованих компонентів і можливостей Blazor

Blazor також містить багато нових вбудованих компонентів і можливостей, які підвищують продуктивність і допомагають швидко виконувати роботу.


Blazor тепер постачається з QuickGrid, швидким і функціональним компонентом сітки даних для обробки найпоширеніших потреб даних. QuickGrid може завантажувати строго типізовані дані з різноманітних джерел даних, включаючи Entity Framework Core, і ви можете швидко під’єднати QuickGrid до наявної моделі даних за допомогою нового скаффолдера Blazor CRUD. Він підтримує сортування, фільтрацію, сторінку та віртуалізацію. Перегляньте демонстраційний сайт QuickGrid , щоб побачити компонент у дії.


Blazor також тепер підтримує розділи, які є виходами для вмісту, який можна заповнити іншими компонентами за допомогою нових компонентів SectionOutlet та SectionContent. Розділи – це чудовий спосіб визначити точки доступу в макеті вашого додатку, які потім можна налаштувати на окремих сторінках.


Маршрутизація в Blazor також отримала значне оновлення в .NET 8. Маршрутизатор Blazor тепер може маршрутизувати до іменованих елементів за допомогою стандартних фрагментів URL-адреси, і тепер ви можете використовувати більшість функцій маршрутизації ASP.NET Core під час визначення маршрутів сторінок Blazor, як-от визначення обмежень маршруту.

Покращення .NET WebAssembly

Виконання вашого коду .NET на WebAssembly з браузера значно покращено в .NET 8. Ваш .NET код працює набагато швидше завдяки новому середовищу виконання на основі Jiterpreter, яке забезпечує часткову підтримку компіляції just-in-time (JIT) для WebAssembly. З новим середовищем виконання компоненти рендеряться на 20% швидше, а десеріалізація JSON відбувається вдвічі швидше!


Середовище виконання .NET WebAssembly також підтримує багато нових типів редагування за допомогою гарячого перезавантаження, включаючи повний паритет із можливостями гарячого перезавантаження CoreCLR і редагування загальних типів.


Новий зручний для мережі формат пакування для програм Blazor WebAssembly, який називається WebCIL, спрощує розгортання, видаляючи всі біти, специфічні для Windows, із ваших збірок .NET і перепаковуючи їх у файли WebAssembly. За допомогою WebCIL ви можете впевнено розгортати свої програми Blazor WebAssembly.

Новий шаблон Blazor Web App

Почати роботу з усіма новими функціями Blazor у .NET 8 легко за допомогою нового шаблону проєкту Blazor Web App. Це ваше єдине місце для всіх ваших потреб у веб-розробці.

Шаблон Blazor Web App

Шаблон Blazor Web App містить зручні параметри для:


Тип автентифікації: швидко налаштуйте автентифікацію за допомогою ASP.NET Core Identity з інтерфейсом користувача, повністю реалізованим за допомогою компонентів Blazor.

 Інтерактивний режим візуалізації: виберіть, які інтерактивні режими візуалізації ви хочете ввімкнути: сервер, WebAssembly або обидва з автоматичним.

Інтерактивне розташування: визначте, чи хочете ви, щоб уся ваша програма була інтерактивною, чи лише окремі компоненти та сторінки.

Додайте зразки сторінок: виберіть, щоб включити кілька зразків сторінок, щоб розпочати роботу, або просто почніть із порожнього проєкту.



Параметри шаблону Blazor Web App

Щоб спробувати створити свій перший вебдодаток Blazor Web App за допомогою .NET 8, просто перейдіть на сторінку https://blazor.net і натисніть «Почати» , щоб розпочати навчання Blazor.


Новий Blazor scaffolder (прев’ю)

Ви можете швидко розпочати роботу зі статичним рендерингом сервера Blazor і QuickGrid, щоб відображати дані з бази даних за допомогою нового скаффолдера Blazor, який тепер доступний з останньою версією Visual Studio Preview. Ви можете використовувати Blazor scaffolder, клацнувши правою кнопкою миші на проєкт в Solution Explorer і вибравши Add > New Scaffolded Item, а потім вибравши Razor Components using Entity Framework (CRUD).

Риштувальник Blazor

Скаффолдер Blazor генерує основні сторінки створення, читання, оновлення та видалення (CRUD) на основі моделі даних Entity Framework Core. Ви можете створювати окремі сторінки або всі сторінки CRUD за один раз. Ви вибираєте клас моделі та DbContext, що слід використовувати, за потреби створюючи новий DbContext.

Варіанти будівельних лісів Blazor

Потім до вашого проєкту буде додано створені компоненти Blazor, щоб увімкнути операції CRUD у вибраному класі моделі.

Компоненти Scaffolded Blazor

Зверніть увагу, що ці сторінки базуються на візуалізації на стороні сервера, тому вони не підтримуються під час роботи на WebAssembly.


Згенерований компонент Index.razor QuickGrid використовується для відображення даних, тому ви можете легко налаштувати спосіб відображення даних і ввімкнути інтерактивність, щоб скористатися перевагами багатьох його функцій.


Ось приклад того, як виглядають компоненти скаффолдера під час роботи програми:

Скаффолдований інтерфейс користувача Blazor із QuickGrid

Типові атрибути для MVC

Атрибути MVC, які раніше вимагали параметрів Type, тепер доступні як загальні атрибути для набагато чистішого синтаксису.


Наприклад, тепер ви можете вказати тип відповіді для дії контролера API таким чином:

Ви можете знайти повний список нових загальних атрибутів для MVC у примітках до релізу.

Кінцеві точки API ідентифікації

ASP.NET Core тепер надає кінцеві точки API для взаємодії з ASP.NET Core Identity. Ці кінцеві точки забезпечують програмний доступ до функціональних можливостей для реєстрації та входу користувачів, що спрощує налаштування автентифікації для браузера та мобільних клієнтських програм. Кінцеві точки можна використовувати як для аутентифікації на основі файлів cookie, так і для автентифікації на основі маркерів. Перегляньте публікацію в блозі Джеремі Лікнесса про те, що нового в ідентифікації в .NET 8, щоб дізнатися все про те, як налаштувати та використовувати ці нові кінцеві точки.

Покращене прив’язування форм для мінімальних API і проміжного програмного забезпечення для захисту від підробки

ASP.NET Core додає підтримку проміжного програмного забезпечення для захисту від підробки, яке підтримує перевірку маркерів захисту від підробки в запитах у всіх реалізаціях фреймворку (Blazor, мінімальні API, MVC). Крім цього, зв’язування форм у мінімальних API також покращено завдяки підтримці зв’язування складних типів із вхідних даних форми, використовуючи ту саму логіку зв’язування, яку спільно використовує Blazor.

Перепідключення SignalR із збереженням стану

SignalR тепер може зменшити відчутний час простою для клієнтів, коли відбувається тимчасове роз’єднання мережевого з’єднання, наприклад, при перемиканні мереж або короткочасній втраті зв’язку. Ви можете налаштувати SignalR на повторне підключення з урахуванням стану, яке налаштує клієнта та сервер на повторне відтворення повідомлень, які могли бути надіслані, коли з’єднання не було. SignalR автоматично подбає про буферизацію повідомлень і відстеження того, які повідомлення вже отримані.

Підтримка ключових служб при ін’єкційній залежності

ASP.NET Core тепер підтримує використання ключових служб під час ін’єкції залежностей (іноді їх називають «Keyed DI»). Keyed DI дозволяє мати кілька реалізацій певної служби, які відрізняються за допомогою зручної для розробника назви. Наприклад, ви можете мати підключення до бази даних для профілів користувачів під назвою «UserProfiles» і інше для вмісту кошика під назвою «ShoppingCarts».

Keyed DI є особливо цінним у сценаріях, коли потрібні різні реалізації служби за різних умов. Наприклад, у програмах з кількома клієнтами це дозволяє використовувати послуги, що стосуються кожного клієнта, забезпечуючи налаштування та масштабованість без ускладнення кодової бази. Він також важливий для керування функціями, дозволяючи динамічно перемикати функції або безперебійно тестувати різні реалізації. Цей рівень контролю та модульності є значним кроком уперед для розробників, які прагнуть створити чистий код, який зручно підтримувати та адаптувати.

Реєстрація та використання сервісів із ключами інтуїтивно зрозумілі та гнучкі. Ось короткий огляд того, як це працює:

Реєстрація ключових послуг:

 

Сервіси з ключем реєструються в колекції сервісів за допомогою унікальних ключів:

Цей підхід дозволяє асоціювати один і той самий інтерфейс з різними реалізаціями, кожна з яких ідентифікується унікальним ключем.

Використання ключових служб:

Ключові служби підтримуються в контролерах, мінімальному API та SignalR.

Щоб скористатися підтримкою нових ключових служб, додайте цільовий параметр до атрибута [FromKeyedServices(“keyName”)].


Наприклад, ось приклади використання ключових служб у контролерах і мінімальних API:


У контролерах MVC:

У мінімальних API:


Подібним чином у мінімальних налаштуваннях API ін’єкція кількох ключових служб у кінцеві точки спрощена:

Ви можете дізнатися більше про ключові служби з документів щодо впровадження залежностей .

Метрики

Метрики – це числові вимірювання, які отримуються протягом певного часу, як-от отримані запити за секунду або кількість надісланих відповідей на помилки. Показники використовуються для моніторингу справності додатків і попередження.


ASP.NET Core тепер надає широкі показники часу виконання за допомогою System.Diagnostics.Metrics , нового крос-платформного API, розробленого в тісній співпраці зі спільнотою OpenTelemetry .


Ці нові показники вносять багато покращень порівняно з наявними лічильниками подій:


– Нові види вимірювань за допомогою лічильників, датчиків і гістограм.

– Потужні звіти з багатовимірними значеннями.

– Інтеграція в ширшу нативну хмарну екосистему шляхом узгодження зі стандартами OpenTelemetry.


Ви можете прочитати все про нові показники, доступні в ASP.NET Core, і про те, як їх інтегрувати у ваші системи моніторингу, у документації про показники ASP.NET Core .


Популярним способом використання показників є Grafana, хмарний інструмент візуалізації даних OSS. Команда .NET опублікувала інформаційні панелі Grafana, створені на основі нових показників. Інформаційні панелі дозволяють у режимі реального часу бачити статус ваших програм ASP.NET Core.

Інформаційна панель .NET Grafana

Завантажте інформаційні панелі безпосередньо з .NET team @ grafana.com і дізнайтеся більше на .NET Grafana dashboards .

Транспортування іменованих каналів

ASP.NET Core тепер надає транспорт іменованих каналів для міжпроцесного зв’язку (IPC) у Windows. Іменовані канали добре інтегруються з безпекою Windows для контролю доступу клієнта до каналу. Перегляньте документацію ASP.NET Core про зв’язок між процесами за допомогою gRPC , щоб дізнатися все про налаштування IPC за допомогою іменованих каналів або сокетів домену Unix.

Кешування виводу на основі Redis

ASP.NET Core у .NET 8 додає підтримку використання Redis як розподіленого кешу для кешування вихідних даних. Кешування вихідних даних забезпечує гнучкий спосіб кешування HTTP-відповідей із сервера. Використання Redis для зберігання кешу забезпечує узгодженість між серверними вузлами через спільний кеш, який переживає окремі серверні процеси.

Оснащення маршруту

Маршрутизація запитів є ключовою частиною будь-якої вебпрограми. Нові функції інструментів для маршрутів у Visual Studio роблять роботу з маршрутами ASP.NET Core простішою, ніж будь-коли раніше. Ці функції включають:

– Підсвічування синтаксису маршруту

– Доповнення редактора для відповідності назв параметрів і маршрутів

– Доповнення редактора для обмежень маршруту

– Аналізатори маршрутів і виправлення типових синтаксичних помилок


Наприклад, ось як виглядають маршрути з .NET 7:

Інструменти маршруту .NET 7

А ось як вони виглядають у .NET 8:

Інструменти маршруту .NET 8

Ви можете прочитати все про нові функції інструментів для маршрутів у дописі в блозі Джеймса Ньютона-Кінга ASP.NET Core Route Tooling Enhancements in .NET 8 .

Покращення дебагування

Потужний дебагер .NET відіграє вирішальну роль у розробці будь-якої програми .NET, і ASP.NET не є винятком. У .NET 8 ми покращили можливість візуалізації налагодження для типів, які часто використовуються в програмах ASP.NET Core, щоб дебагер відразу відкривав найважливішу інформацію.


Наприклад, ось як виглядає перевірка HttpContext за допомогою .NET 7:

 

Налагодження HttpContext з .NET 7

Ось як це виглядає з .NET 8, де найважливіші значення видно одразу:

Налагодження HttpContext з .NET 8

Ознайомтеся з усіма новими вдосконаленнями налагодження ASP.NET у публікації Джеймса Ньютона-Кінга про вдосконалення налагодження в .NET 8 .


JavaScript SDK і система проєктів

Часто під час роботи з ASP.NET Core вам також потрібно працювати з JavaScript та екосистемою JavaScript. Поєднання світу .NET і JavaScript може бути складним завданням. Новий SDK для JavaScript і система проєктів у Visual Studio спрощують використання .NET із зовнішніми фреймворками JavaScript. JavaScript SDK забезпечує інтеграцію MSBuild для створення, запуску, налагодження, тестування та публікації коду JavaScript або TypeScript разом із кодом .NET. Ви можете легко інтегрувати такі популярні інструменти створення JavaScript, як WebPack, Rollup, Parcel, esbuild та інші.


Ви можете швидко почати використовувати ASP.NET Core з Angular, React і Vue за допомогою наданих шаблонів Visual Studio:

SPA шаблони

Ці шаблони доступні як для JavaScript, так і для TypeScript і використовують найновіший інтерфейсний інструмент JavaScript CLI для створення клієнтської програми, тож ви завжди будете в курсі останньої версії.


Ви можете скористатися діалоговим вікном «Install New npm Packages», щоб легко знайти та встановити залежності npm:

Діалогове вікно встановлення нових пакетів npm

Коли ви створюєте свій проєкт JavaScript, JavaScript SDK встановить будь-які залежності пакетів npm. Потім ви можете запустити програму з Visual Studio або в командному рядку за допомогою dotnet run. У Visual Studio ви отримуєте розширену підтримку налагодження коду .NET і JavaScript.


Ви також можете використовувати Visual Studio Test Explorer, щоб виявити та запустити свої тести:

Test Explorer для тестів JavaScript

Ви можете дізнатися більше про спільну роботу з .NET і JavaScript у Visual Studio в документах Visual Studio для JavaScript.

І ще багато іншого!

Це лише приклад того, що нового в ASP.NET Core для .NET 8. Щоб отримати повний список, перегляньте примітки до випуску ASP.NET Core у .NET 8.

Оновити наявний проєкт

Щоб оновити наявну програму ASP.NET Core з .NET 7 до .NET 8, виконайте дії, описані в розділі Перехід з ASP.NET Core 7.0 на 8.0


Щоб оновити наявну програму ASP.NET Core з .NET 8 RC2 до .NET 8, оновіть усі посилання на пакет ASP.NET Core до 8.0.0.. У Blazor Web Apps також слід замінити попередні атрибути режиму візуалізації новою директивою  @rendermode:

Додайте @using static Microsoft.AspNetCore.Components.Web.RenderMode до вашого файлу _Imports.razor

– Замініть @attribute [RenderModeInteractiveServer] на @rendermode InteractiveServer

– Замініть @attribute [RenderModeInteractiveWebAssembly]на @rendermode InteractiveWebAssembly

– Замініть@attribute [RenderModeInteractiveAuto] на @rendermode InteractiveAuto

Це воно! І ви готові користуватися перевагами .NET 8.

Дивіться також повний список критичних змін у ASP.NET Core для .NET 8.


.NET 8 на Azure

.NET 8 уже розгорнуто та готово до використання з усіма вашими улюбленими службами Azure, включаючи службу додатків Azure, функції Azure та статичні веб-програми Azure. Почніть працювати з .NET 8 на Azure вже сьогодні!

Легко створюйте хмарні програми за допомогою .NET Aspire і ASP.NET Core

.NET 8 представляє інтегрований підхід до хмарних додатків через .NET Aspire, створений з використанням надійних можливостей ASP.NET Core. Ця співпраця пропонує розробникам ASP.NET знайоме середовище для використання наявних навичок, водночас користуючись перевагами продуманого стеку, розробленого для стійкості, спостережливості та конфігурованості в хмарі. .NET Aspire плавно покращує ASP.NET Core, включаючи такі основні хмарні компоненти, як телеметрія, стратегії стійкості, керування конфігураціями та готові перевірки справності. Для плавного переходу до хмарної розробки за допомогою інструментів, які ви знаєте і яким довіряєте, ознайомтеся з анонсом .NET Aspire і дізнайтеся, як це може оптимізувати розробку ваших програм у хмарі.

Дякуємо!

Дякуємо всім у спільноті, хто допоміг зробити цей реліз .NET 8 можливим! Цей реліз являє собою кульмінацію багатьох проблем GitHub, запитів, коментарів щодо відгуків про дизайн та оновлень документації, внесених багатьма членами спільноти .NET. Без вас ми б не досягли цього!


Ми сподіваємося, що вам сподобається цей випуск ASP.NET Core у .NET 8. Ми з нетерпінням чекаємо почути про ваш досвід роботи з ним. Надсилайте нам будь-які ваші відгуки щодо цього релізу на GitHub.


Ще раз дякую та щасливого кодування!






Posted on 10. October 2023

C# Dev Kit – Now Generally Available

C# Dev Kit – тепер загальнодоступне

Радо повідомляємо про загальну доступність C# Dev Kit, розширення коду Visual Studio, яке покращує процес розробки на C#  для Linux, macOS та Windows.

C# Dev Kit

Подяка зусиллям спільноти!

 

З моменту першого попереднього перегляду в червні було отримано як кількісні дані, так і неоціненні відгуки спільноти, які допомогли сформувати цей продукт. Було вирішено близько 350 проблем, про які переважно повідомляла спільнота. Ці вдосконалення охоплюють як покращення якості, так і роз’яснення сценаріїв. Завдяки активній участі користувачів було зроблено понад 300 цілеспрямованих удосконалень, що дозволило зробити розширення більш надійним і безпечним. Ці спільні зусилля стали вирішальними у рішенні перейти від попереднього перегляду до загальної доступності та розпочати офіційну підтримку для підписників Visual Studio.

Що таке C# Dev Kit?

C# Dev Kit використовує основні можливості мови C# і надає розробникам додаткові можливості для продуктивної роботи. Хоча ці основні функції вже стали загальнодоступними, додаткові можливості, що підтримують .NET MAUI та Unity, все ще перебувають у стадії попереднього перегляду, використовуючи C# Dev Kit. Ці розширення продовжують отримувати відгуки та покращувати робочі процеси розробки для MAUI та Unity у VS Code.

Переглядайте корисну інформацію у цьому відео!

Майбутні плани щодо C# Dev Kit

Сьогоднішній офіційний запуск – це лише початок, оскільки надалі планується випускати оновлення розширення щомісяця, прислухаючись до відгуків користувачів та працюючи над покращенням продуктивності, надійності та додаванням нових функцій для підтримки розробки на C# у VS Code. Якщо ви бажаєте отримувати оновлення раніше, підпишіться на канал попередніх випусків, де будуть публікуватися виправлення та анонси нових функцій в міру їх розробки.

Будь ласка, діліться своїми відгуками, повідомляйте про нові проблеми за допомогою коду VS або здійснюйте пошук наявних удосконалень і проблем, а також ставте “великий палець вгору” або надавайте додатковий контекст проблеми, щоб допомогти розставити пріоритети.

Дізнатися більше

Якщо ви хочете дізнатися більше про C# Dev Kit, ви можете відвідати кілька чудових сесій на Ignite та .NET Conf у листопаді або ознайомитися з оновленою документацією C# VS Code та інструкціями з початку роботи. Спробуйте нове середовище C# з C# Dev Kit вже сьогодні!

 

Встановити C# Dev Kit



Posted on 7. October 2023

C# Dev Kit – Now Generally Available

C# Dev Kit – тепер загальнодоступний

Сьогодні ми раді повідомити про загальну доступність C# Dev Kit, розширення Visual Studio Code, яке надає покращений досвід розробки на C# для Linux, macOS і Windows.

C# Dev Kit

Зусилля спільноти – дякуємо!

З моменту попереднього прев’ю в червні ми отримали дані, що піддаються кількісному вимірюванню, і безцінні відгуки спільноти, які сформували цей продукт. Було розглянуто приблизно 350 питань, про які нам в основному повідомляла спільнота. Ці покращення варіюються від покращення якості до уточнення сценарію. Ваша активна участь призвела до понад 300 цілеспрямованих покращень, які зробили розширення надійнішим і надійнішим. Ці спільні зусилля мали вирішальне значення для нашого рішення перейти від попереднього перегляду до загальної доступності та започаткувати офіційну підтримку для передплатників Visual Studio.

Що таке C# Dev Kit?

C# Dev Kit використовує основні служби мови C# і забезпечує додаткову продуктивність для розробників. Хоча ці основні функції продуктивності зараз загальнодоступні, додаткові можливості, які підтримують .NET MAUI та Unity , все ще перебувають у версії прев’ю, використовуючи C# Dev Kit. Ці розширення продовжують отримувати користь від відгуків і покращують ваші робочі процеси розробки для MAUI та Unity у VS Code.


Перегляньте відео 

Що далі для C# Dev Kit

Сьогоднішній офіційний запуск — це лише початок, оскільки ми продовжуватимемо прислухатися до ваших відгуків і працювати над покращенням продуктивності, надійності та додаванням функцій для підтримки вашої розробки C# у VS Code з оновленнями розширення щомісячно. Якщо ви хочете отримати перші частини, підпишіться на канал прев’ю, де ми будемо додавати виправлення та попередній перегляд нових функцій у міру їх розробки.

Будь ласка, поділіться своїм відгуком, повідомивши про нові проблеми через код VS або здійснивши пошук серед наявних удосконалень і проблем, а також поставте «великий палець» або додайте контекст до проблеми, щоб допомогти нам визначити пріоритети.

Вивчайте більше

 

Якщо ви хочете дізнатися більше про C# Dev Kit, ви можете відвідати кілька чудових сесій, які відбудуться на Ignite та .NET Conf у листопаді, або ознайомитися з нашою оновленою документацією C# VS Code та документацією «Початок роботи». Спробуйте нове середовище C# із C# Dev Kit сьогодні!




Posted on 25. July 2023

ASP.NET Core updates in .NET 8 Preview 6

Оновлення ASP.NET Core в .NET 8 Preview 6

.NET 8 Preview 6 вже доступна і містить багато нових чудових покращень в ASP.NET Core.

Ось короткий огляд новинок цієї попередній версії:

Покращено налагодження під час запуску

Blazor.

Прив’язка та валідація моделі форми з рендерингом на стороні сервера

Покращена навігація сторінками та обробка форм

Збереження наявних DOM-елементів за допомогою потокового рендерингу

Можливість вказати режим рендерингу компонентів на сайті виклику

Інтерактивний рендеринг з Blazor WebAssembly

Покращення розділів

Каскадний запит значень рядків до компонентів Blazor

Опція шаблону Blazor Web App для включення серверної інтерактивності

Консолідація шаблону Blazor

Метрики

Тестування метрик у додатках ASP.NET Core

Нові, покращені та перейменовані лічильники

Розробка API

Підтримка зв’язування складних форм у мінімальних API

Сервери та проміжне програмне забезпечення

Буферизація відповідей ядра HTTP.sys

Вихідний кеш на основі Redis

Щоб дізнатися більше про заплановані роботи над ASP.NET Core для .NET 8, дивіться повний опис ASP.NET Core для .NET 8 на GitHub.

Розпочнімо.

Щоб почати роботу з ASP.NET Core в .NET 8 Preview 6, встановіть .NET 8 SDK.

Якщо ви використовуєте Visual Studio на Windows, рекомендується встановити останню версію Visual Studio 2022 preview. Якщо ви використовуєте Visual Studio Code, ви можете спробувати нове розширення C# Dev Kit. Якщо ви використовуєте macOS, то можете працювати за допомогою Visual Studio для Mac 17.6.1, увімкнувши функцію preview для .NET 8 у Налаштуваннях.

Оновлення наявного проєкту

Щоб оновити наявний додаток ASP.NET Core з .NET 8 Preview 5 до .NET 8 Preview 6:

Оновіть цільовий фреймворк вашого додатка до net8.0.

Оновіть усі посилання на пакунок Microsoft.AspNetCore.* до версії 8.0.0-preview.6.*.

Оновіть усі посилання на пакунок Microsoft.Extensions.* до версії 8.0.0-preview.6.*.

Дивіться також повний список суттєвих змін в ASP.NET Core для .NET 8.

Покращений досвід налагодження під час запуску

У минулій попередній версії було представлено поліпшення налагодження для HttpContext. У .NET 8 Preview 6 покращено налагодження для типу WebApplication.

WebApplication – це спосіб за замовчуванням для налаштування та запуску додатків ASP.NET Core у Program.cs. Атрибути налагодження були застосовані до WebApplication, щоб виділити важливу інформацію, таку як налаштовані кінцеві точки, проміжне програмне забезпечення та значення IConfiguration у налагоджувачі вашого IDE.

.NET 7

WebApplication debugging before

.NET 8

WebApplication debugging after

Дивіться ASP.NET Core Налагодження GitHub для отримання додаткової інформації про покращення налагодження в .NET 8.

 

Blazor

Зв’язування та валідація моделі форми з рендерингом на стороні сервера

Новий режим рендерингу на стороні сервера Blazor тепер може моделювати зв’язування і перевіряти значення постів HTTP-форм.

Щоб прив’язати дані із запиту форми, застосуйте атрибут [SupplyParameterFromForm] до властивості компонента. Дані в запиті, які відповідають назві властивості, будуть прив’язані до цієї властивості. Властивість може бути примітивним типом, складним типом, колекцією або словником. Також підтримується перевірка на стороні сервера за допомогою анотацій даних.

 

Movie.cs

Якщо на сторінці є кілька форм, їх можна розрізнити за допомогою параметра Name, і ви можете використовувати властивість Name на [SupplyParameterFromForm], щоб вказати, з якої форми ви хочете зв’язати дані.

Вам більше не потрібно налаштовувати компонент CascadingModelBinder, щоб увімкнути прив’язку моделей. Тепер він налаштований для вас автоматично.

Покращена навігація сторінками та обробка форм

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

У цій попередній версії покращена навігація та обробка форм ще не сумісна з одночасною наявністю на сторінці інтерактивних (серверних або WebAssembly) компонентів. Якщо ваш додаток використовує інтерактивні компоненти, розширену навігацію буде автоматично вимкнено. Це обмеження буде усунуто в наступній попередній версії перед випуском .NET 8 GA.

Збереження наявних DOM-елементів за допомогою потокового рендерингу

Потоковий рендеринг Blazor тепер зберігає наявні DOM-елементи під час потокової передачі оновлень на сторінку, що забезпечує швидший і простіший користувацький інтерфейс.

Можливість вказати режим рендерингу компонентів на сайті виклику

Тепер ви можете вказати режим рендерингу для екземпляра компонента за допомогою атрибута директиви @rendermode. Режим рендерингу буде застосовано до компонента та його дочірніх елементів. Наприклад, 

@rendermode=“@RenderMode.Server” />


Щоб увімкнути використання call site @rendermode, переконайтеся, що у файлі проєкту встановлено версію мови Razor 8.0. Це буде оброблено внутрішньо у фреймворку і не буде необхідним, починаючи з наступного релізу. Для цього відредагуйте файл .csproj вашого проєкту, додавши в перший елемент наступний рядок: 8.0

Інтерактивний рендеринг з Blazor WebAssembly

Тепер ви можете увімкнути інтерактивний рендеринг компонентів за допомогою Blazor WebAssembly. Хоча ця опція ще не доступна у шаблоні вебпрограми Blazor, ви можете увімкнути її вручну.

Щоб увімкнути підтримку режиму рендерингу WebAssembly у вашому проєкті Blazor, додайте відповідні служби викликом app.Services.AddRazorComponents().AddWebAssemblyComponents() і додайте режим рендерингу WebAssembly викликом app.MapRazorComponents().AddWebAssemblyRenderMode(). Будь-які компоненти, які ви хочете рендерити на WebAssembly, потрібно буде завантажити разом з усіма їхніми залежностями у браузер. Вам потрібно буде створити окремий проєкт Blazor WebAssembly для створення будь-якого специфічного коду для WebAssembly і посилатися на нього з вашого додатка Blazor.

Ви можете вказати режим інтерактивного рендерингу WebAssembly для компонента, додавши атрибут [RenderModeWebAssembly] до визначення компонента або вказавши @rendermode=“@RenderMode.WebAssembly” у екземплярі компонента. Компоненти, які ви налаштували на рендеринг у WebAssembly, за замовчуванням також будуть попередньо рендеритися з сервера, тому переконайтеся, що ваші компоненти будуть коректно рендеритися в обох середовищах, або вимкніть попередній рендеринг при визначенні режиму рендерингу: [RenderModeWebAssembly(prerender: false)] або @rendermode=“@(new WebAssemblyRenderMode(prerender: false)).

Ось приклад, що демонструє, як налаштувати інтерактивність на основі WebAssembly для компонента Counter, який виводиться зі сторінки Index .

Зауважте, що наразі існує обмеження, згідно з яким компоненти з маршрутами мають бути визначені у тій самій збірці, що й компонент App, переданий до MapRazorComponents(), тому наразі їх не можна визначити у клієнтській збірці. Ця проблема буде вирішена у майбутньому оновленні.

Покращення розділів Blazor

Ми зробили наступні покращення у взаємодії розділів Blazor з іншими функціями Blazor:

Каскадні значення: Каскадні значення тепер потраплятимуть у вміст секції з місця визначення вмісту, а не з місця його виведення у виводі секції.

Межі помилок: Необроблені винятки тепер оброблятимуться межами помилок, визначеними навколо вмісту секції, а не навколо виводу секції.

Потоковий рендеринг: Використання потокового рендерингу для вмісту секції тепер визначається компонентом, у якому визначено вміст секції, а не компонентом, у якому визначено вивід секції.

Каскадний запит значень рядків до компонентів Blazor

 

Тепер ви можете отримувати значення параметрів рядка запиту в будь-якому компоненті, а не тільки в компонентах @page, використовуючи атрибут [SupplyParameterFromQuery]. Наприклад:

[SupplyParameterFromQuery]

public int PageIndex { get; set; }


Більше не потрібно додавати атрибут [Parameter] до будь-якої властивості, яка оголошує [SupplyParameterFromQuery].

Опція шаблону Blazor Web App для включення серверної інтерактивності

Шаблон Blazor Web App тепер надає опцію у Visual Studio для включення інтерактивності за допомогою режиму серверного рендерингу:

Blazor template option for server interactivity

Ця ж опція вже доступна з командного рядка:

dotnet new blazor —use-server


Консолідація шаблону Blazor

У рамках об’єднання різних моделей хостингу Blazor в єдину модель в .NET 8, також консолідовано кількість шаблонів проєктів Blazor. У цій попередній версії видалено шаблон Blazor Server і опцію ”ASP.NET Core hosted“ з шаблону Blazor WebAssembly. Обидва ці сценарії будуть представлені у вигляді опцій при використанні нового шаблону Blazor Web App.

 

Метрики

Тестування метрик у додатках ASP.NET Core

У попередній версії .NET 8 було представлено метрики ASP.NET Core. Тепер стало простіше тестувати метрики в додатках ASP.NET Core.

ASP.NET Core використовує API IMeterFactory для створення та отримання показників. IMeterFactory особливо корисний для модульного тестування, коли кілька тестів можуть виконуватися паралельно, і ви хочете зібрати дані тільки для вашого тесту. 

 

У прикладі нижче показано, як використовувати IMeterFactory і MetricCollector (спрощений спосіб збору даних показників) у функціональному тесті ASP.NET Core:

Нові, покращені та перейменовані лічильники

ASP.NET продовжує покращувати підтримку метрик, додаючи нові лічильники та вдосконалюючи наявні. Це дозволить зробити додатки ASP.NET Core помітними в інформаційних панелях звітів і увімкнути користувацькі сповіщення.

Нові лічильники в цьому випуску:

routing-match-success і routing-match-failure повідомляють про те, як запит було направлено в додатку. Якщо запит успішно збігається з маршрутом, лічильник містить інформацію про шаблон маршруту і про те, чи був це запасний маршрут.

diagnostics-handler-exception додано до проміжного програмного забезпечення обробки винятків. Лічильник повідомляє про те, як обробляються необроблені винятки, і містить інформацію про назву винятку та результат обробника.

http-server-unhandled-requests – це новий лічильник у хостингу ASP.NET Core. Він повідомляє, коли HTTP-запит досягає кінця конвеєра проміжного програмного забезпечення, не бувши обробленим додатком.

Різноманітні нові лічильники проміжного програмного забезпечення, що обмежують швидкість, дають змогу спостерігати за кількістю запитів у стані очікування, кількістю запитів у черзі, тривалістю черги тощо.

Покращені лічильники:

kestrel-connection-duration тепер містить протокол з’єднання HTTP і протокол TLS.

signalr-http-transport-current-connections тепер містить тип транспортного з’єднання.

Окрім того, на основі тестування ASP.NET Core за допомогою хмарних інструментів, було перейменовано всі лічильники ASP.NET Core, щоб надати в назву більше інформації. Лічильники було перейменовано, щоб їх можна було ідентифікувати лише за назвою та зменшити ймовірність конфліктів імен. Наприклад, request-duration було перейменовано на http-server-request-duration.

Розробка API

Підтримка зв’язування складних форм у мінімальних API

У .NET 8 Preview 4 розширено підтримку зв’язування форм у мінімальних API для обробки певних параметрів на основі форм без використання атрибута FromForm. Це було обмежено типами параметрів, включаючи IFormCollection, IFormFile і IFormFileCollection. Мінімальні API тепер підтримують прив’язку до форми для складніших сценаріїв, зокрема:

Колекцій, таких як List і Dictionary

 

Складних типів, таких як Todo або Project

У наведеному нижче прикладі показано мінімальну кінцеву точку, яка зв’язує багатокомпонентний ввід форми зі складним об’єктом. Він також показує, як використовувати служби захисту від підробок в ASP.NET для підтримки генерації та перевірки токенів від підробок в мінімальних API. Ключові моменти, на які слід звернути увагу в цьому прикладі, включають

Цільовий параметр має бути анотований атрибутом [FromForm], щоб відрізнити його від параметрів, які мають бути прочитані з JSON body.

Прив’язка до типів record  наразі не підтримується, тому складні типи мають бути реалізовані як клас.

Рекурсивне зв’язування не підтримується, тому тип Todo не містить рекурсивних посилань.

Сервери та проміжне програмне забезпечення

Буферизація відповідей ядра HTTP.sys

Тепер ви можете ввімкнути буферизацію відповідей на основі ядра при використанні HTTP.sys за допомогою параметра EnableKernelResponseBuffering. Ця опція може покращити час відповіді, особливо при написанні великих відповідей з великою кількістю дрібних записів до клієнта з великою затримкою. У відповідних сценаріях це може значно покращити час відповіді з хвилин (або повної відсутності) до секунд.

Кешування виводу на основі Redis

Кешування виводу було введено в .NET 7 і дозволяє кешувати й відтворювати відповіді цілком, зменшуючи час обробки на сервері. За замовчуванням, кешовані відповіді зберігаються в процесі роботи, тому кожен вузол сервера має окремий ізольований кеш, який втрачається при перезапуску серверного процесу. Тепер доступна можливість використовувати бекенд Redis для кешування вихідних даних, що забезпечує узгодженість між вузлами сервера за допомогою спільного кешу, який не залежить від окремих серверних процесів.

 

Щоб налаштувати кешування виводу на основі Redis, додайте посилання на пакет Microsoft.Extensions.Caching.StackExchangeRedis, а потім налаштуйте необхідні служби, викликавши app.Services.AddStackExchangeRedisOutputCache(…). Доступні опції конфігурації ідентичні наявним опціям розподіленого кешування на основі Redis. Ви можете надати власний сервер Redis або скористатися послугами хостингу, наприклад, Azure Cache для Redis.





Posted on 7. May 2023

Анонсуємо нову версію .NET Upgrade Assistant з підтримкою .NET MAUI та Azure Functions!

та

 

Ми раді повідомити, що ми випустили нову версію .NET Upgrade Assistant у Visual Studio, яка робить ваше оновлення до найновішої версії .NET framework ще простішим!


.NET Upgrade Assistant - це інструмент, який допоможе вам оновити ваш додаток до найновішої версії .NET та перейти зі старих платформ, таких як Xamarin Forms та UWP, на новіші пропозиції. У лютому ми випустили розширення Visual Studio для цього інструменту, а зараз вийшла нова версія з багатьма покращеннями та новими функціями. Переконайтеся, що у вас увімкнено автоматичне оновлення для цього інструменту, щоб отримати найкращі результати. У Visual Studio | Extensions | Manage Extensions знайдіть .NET Upgrade Assistant у розділі Installed і переконайтеся, що позначку Автоматично оновлювати це розширення встановлено. Запустіть Visual Studio від імені адміністратора, щоб внести ці зміни, якщо потрібно.

 

Що нового в цій версії

Ми раді повідомити, що в цьому випуску додано підтримку нових сценаріїв для різних платформ, фреймворків тощо! Ось деякі з нових покращень:

 

  • Підтримка .NET 8.
  • Оновлення з Xamarin.Forms до .NET MAUI.
  • Оновлення для функцій Azure.
  • Оновлення з UWP на WinUI.
  • Підтримка ARM64.

Оновлення та вдосконалення

Ця версія також включає декілька удосконалень, про які просили розробники і які покращують загальний досвід використання .NET Upgrade Assistant:

 

  • Покращено спосіб оновлення пакунків NuGet за допомогою Помічника з оновлення.
  • Оновлений сценарій Incremental для використання YARP 2.0.
  • Покращено обробку помилок, тепер всі збої та попередження можна побачити у вікні прогресу для кожного компонента проекту.
  • Численні інфраструктурні оновлення рушія інструменту, які покращили продуктивність та загальну якість оновлень.
  • Підтримка проектів у стилі SDK, які використовують System.Web. Раніше веб-проекти, які були вручну перетворені в SDK-стиль, але все ще використовували System.Web, не могли бути оновлені інкрементально і розглядалися як проекти сімейства Core. Тепер Upgrade Assistant розглядає їх як проекти .NET Framework і дозволяє оновлювати їх поетапно, що є найкращим способом оновлення веб-додатків з .NET Framework до найновіших версій .NET.
  • WinForms - додано обробку для випадків, коли певні API зі старої версії не підтримуються в новій версії .NET.
  • ASP.NET - додано покращення щодо того, як проекти оновлюються за лаштунками.

 


Детальніше про оновлення до .NET 6, 7, 8

У попередній версії Помічника з оновлення, коли ви вибирали оновлення з .NET Core або новішої версії до .NET 6, 7 або 8, Помічник з оновлення оновлював лише цільовий фреймворк. Тепер він також оновлює всі пакунки, на які посилається ваша програма, до цілісного набору пакунків, що відповідає цільовій .NET.


Ось як працює оновлення пакунків:

 

  • Для стандартних пакетів середовища виконання .NET або пакетів ASP.NET Core буде встановлено останню версію відповідного цільового фреймворку 6, 7 або 8. Наприклад, якщо ви оновлюєте свій додаток до .NET 6, ви отримаєте відповідну версію пакета для .NET 6, а якщо ви оновлюєте його до .NET 8, ваші пакети будуть оновлені до останніх передрелізних версій.
  • Для всіх інших пакунків інструмент перевіряє, чи пакунок вже підтримує цільовий фреймворк, у такому випадку пакунок залишається незмінним. Якщо ні, інструмент перевірить, чи остання версія пакунка підтримує цільовий фреймворк, до якого оновлюється програма. Якщо навіть остання версія пакунка не підтримує цільовий фреймворк, цей пакунок буде вилучено.
Ще одна нова функція - підтримка оновлень Preview: тепер ви можете оновити стару версію Preview до найновішої.

 


Оновлення з Xamarin.Forms на .NET MAUI

Тепер ви можете оновити ваші існуючі додатки Xamarin.Forms до наступника Xamarin - .NET MAUI.

У порівнянні з Xamarin.Forms, .NET MAUI має багато переваг та покращень, таких як:

 

  • єдиний проект для спрощення управління активами, управління NuGet та використання багатоцільового таргетингу.
  • багатовіконна підтримка сценаріїв для настільних комп'ютерів та планшетів
  • перебудований макет для покращення зручності супроводу, продуктивності та виправлення багатьох особливостей, присутніх у Xamarin.Forms.
  • Конструктор додатків для стандартизації завантаження додатків за загальним шаблоном .NET
  • Відокремлення платформи від крос-платформних елементів керування
  • Шаблон багаторівневого рендерингу над новими обробниками
  • Рефакторинг реалізацій Shell

 

та багато іншого. Ви можете прочитати документацію по .NET MAUI для більш детальної інформації.

Щоб оновити ваш додаток Xamarin.Forms до .NET MAUI:

 

  • У Visual Studio в Solution Explorer клацніть правою кнопкою миші на одному з ваших проектів і виберіть Upgrade. Вам потрібно встановити розширення Upgrade Assistant Visual Studio, щоб побачити опцію Upgrade. Ви можете почати з будь-якого проекту у вашому рішенні; вам потрібно буде оновити всі проекти, щоб ваш додаток зібрався.

 

 


 

  • Ви побачите головну сторінку з кількома варіантами оновлення.

 

  • Виберіть In place, якщо ви хочете оновити ваш оригінальний проект, або Side-by-side, якщо ви хочете створити новий проект MAUI поруч з вашим оригінальним проектом і залишити оригінальний проект без змін.
  • Дотримуйтесь кроків оновлення. Якщо у вас немає причин для поступового оновлення деяких частин вашого проекту, залиште всі позначки, які пропонує інструмент, і виконайте оновлення.
  • Повторіть це для кожного проекту вашого рішення.
  • Після завершення оновлення ви побачите, що інструмент змінив файли проекту, оновив посилання та вніс інші необхідні зміни. Створіть і запустіть ваші програми. Якщо виникнуть будь-які інші помилки, вам доведеться виправити їх вручну.
Примітка: для перетворень файлів .xaml Помічник оновлення включає базові заміни просторів імен. Для більш складних перетворень .xaml-файлів потрібна Visual Studio 17.6.

 

Оновлення для Azure Functions

Azure Functions - це безсерверна обчислювальна платформа, яка дає змогу запускати код без резервування або керування інфраструктурою. Існує чотири основні версії Azure Functions: 1.x, 2.x, 3.x і 4.x. Кожна версія має свій набір функцій і можливостей.

 

  • Версія 1.x - це найстаріша версія Azure Functions. Вона більше не підтримується і не повинна використовуватися для нових розробок.
  • Версія 2.x була випущена у 2017 році. Це значне оновлення порівняно з версією 1.x, яке включає низку нових функцій, зокрема підтримку декількох мов, покращену продуктивність і гнучкішу модель розгортання.
  • Версія 3.x була випущена в 2018 році. Це незначне оновлення порівняно з версією 2.x, яке включає кілька нових функцій, зокрема підтримку Azure Durable Functions і поліпшену інтеграцію з Azure Event Grid.
  • Версія 4.x була випущена в 2020 році. Це значне оновлення порівняно з версією 3.x, яке включає низку нових функцій, зокрема підтримку .NET 6, покращену продуктивність і більш безпечну архітектуру.

 

Також різні версії функцій Azure підтримуються в різних версіях .NET. У наступній таблиці наведено основні відмінності між різними версіями Azure Functions:

Під час оновлення проекту Azure Functions до останньої версії .NET інструмент автоматично оновить версію Azure Functions до ізольованої версії , оскільки це найкраща та рекомендована версія.

Ви можете оновити проект Azure Functions так само, як і будь-який інший проект, клацнувши правою кнопкою миші на проекті в Провіднику рішень, вибравши опцію Upgrade й дотримуючись вказівок інструмента.


Окрім оновлення файлу проекту до останньої версії .NET і версії Azure Functions, тіло функцій також оновлюється, щоб використовувати нові API.

Ви можете прочитати більше про функції Azure в документації.


Ідемо далі

Далі ми зосередимося на покращенні якості оновлень, стабілізації інструменту, усуненні існуючих помилок та ваших відгуках.


Ми також працюватимемо над оновленням існуючого CLI-інструменту, щоб він працював з тим самим рушієм, що й розширення Visual Studio. Таким чином, інструмент CLI матиме всі нові можливості, які є у VSIX, тож ви зможете обирати між Visual Studio та CLI.


Дізнайтеся, як оновити версію

У автора є багато матеріалів, які допоможуть вам у процесі оновлення:

 

 


Feedback!

Будь ласка, надішліть команді свій відгук, щоб вони могли створити правильні інструменти для вас, заповнивши це коротке опитування.


Ви також можете надсилати проблеми або запити щодо можливостей Visual Studio, вибравши Довідка | Надіслати відгук. У темі листа обов'язково зазначте "Upgrade Assistant vsix". 



 



Exception: Collection was modified after the enumerator was instantiated.
Posted on 20. February 2023

Оновлення .NET проектів за допомогою Visual Studio

Оновлення .NET проектів за допомогою Visual Studio

 

Тепер ви можете оновити будь-яку .NET програму до останньої версії .NET прямо з Visual Studio! Ми раді представити його як розширення Visual Studio, яке дозволить оновити ваші веб- та десктопні додатки на базі .NET Framework або .NET Core. Деякі типи проектів знаходяться в розробці і будуть доступні найближчим часом, дивіться деталі нижче.

 

Навіщо оновлюватись і до якої версії?

 

Якщо ваші програми розроблені на .NET Framework або .NET Core, зараз чудовий час оновити їх до .NET 6 (версія з довгостроковою підтримкою) або .NET 7 (версія зі стандартною підтримкою), які мають набагато кращу продуктивність і надають доступ до найновіших функцій та можливостей. Між .NET Framework та останньою версією .NET відбулися величезні покращення, але навіть якщо ви використовуєте .NET Core 3.1 або більш ранню версію, її підтримка закінчується в грудні 2022 року.

 

The author recommends porting to .NET 6 or .NET 7!

 

Між цими двома версіями .NET 6 має довший час підтримки, а .NET 7 є найновішою, тому має новіші функції. Ми випускаємо нову версію .NET щороку в листопаді, і кожна парна версія підтримується протягом 3 років (довгострокова підтримка, або скорочено LTS). Таким чином, ви можете або залишатися на найновіших передових технологіях і оновлюватись щороку, або переходити з LTS на LTS раз на 2-3 роки.

 

Про Upgrade Assistant

 

Оновлення додатку, особливо з .NET Framework, було складним процесом. Команда продовжує створювати прототипи та вдосконалюватися в цій галузі, щоб спростити оновлення. У минулому ви могли використовувати інструмент Upgrade Assistant CLI або Microsoft Project Migrations. Ваші відгуки було зібрано, велика подяка всім, хто заповнив опитування або залишив коментарі, створив проблеми і запити функцій! Враховуючи ваші відгуки, команда дійшла висновку, що необхідно забезпечити уніфікований досвід оновлення для всіх типів проектів у Visual Studio.

 

Тепер ви зможете оновити будь-який тип .NET-додатків з будь-якої початкової версії (.NET Framework або .NET Core), клацнувши правою кнопкою миші на вашому проекті в Solution Explorer і вибравши “Оновити”. Не забудьте спочатку встановити розширення.


Загальна філософія Upgrade Assistant полягає в тому, що він подбає про механіку, але залежно від того, з якого фреймворку і типу проекту ви оновлюєтесь, вам слід очікувати, що вам доведеться виконати деяку ручну пост-обробку. Хоча команда намагається автоматично виправляти зміни, що порушують роботу фреймворку, він не може виявити і виправити всі з них. Тому вам може знадобитися внести деякі додаткові зміни, щоб змусити код компілюватися, а також ретельно протестувати, щоб переконатися, що ваш код продовжує працювати належним чином.

 

Підтримувані типи програм

Ми прагнемо підтримувати кожен тип .NET проектів. Крім того, ми розглядаємо цей інструмент не лише як одноразове оновлення з .NET Framework до .NET 6/7, але й як спосіб оновити ваш додаток до найновішої версії .NET у майбутньому. Окрім зміни цільової версії фреймворку, інструмент зможе модифікувати ваш код, щоб виправити непрацюючі зміни. Це наші плани на майбутнє, а наразі ось що підтримується інструментом в останній версії:


ASP.NET

Class libraries

Console

WPF

WinForms

 

Ці робочі навантаження є паритетними з інструментом Upgrade Assistant CLI.



Незабаром: 

Міграція з Xamarin на .NET MAUI

Міграція з UWP на WinUI

Міграція WCF на WCF Core


Ці типи міграції знаходяться в розробці, і ви вже можете оновити ці проекти, але у команди ще немає виправлень коду для цих проектів. Якщо вам потрібно перенести ці типи проектів сьогодні, рекомендовано скористатися наявним інструментом командного рядка Upgrade Assistant, який вже має виправлення коду. Розширення Visual Studio також незабаром отримає їх.


Різні типи оновлень

Помічник з оновлення підтримує 3 типи оновлень. Різні типи рекомендуються для різних типів проектів, тому ви побачите лише ті варіанти, які підійдуть для вашого додатку.

In-place. У цьому випадку ваш оригінальний проект буде оновлений одразу. Якщо ви використовуєте контроль вихідних текстів і віддаєте перевагу самостійному управлінню копіями, наприклад, за допомогою гілок, цей варіант для вас.

Side-by-side. За допомогою цієї опції ваш оригінальний проект не буде змінено, а до рішення буде додано його копію, яка міститиме оновлений код. Цей тип може бути зручним, якщо ваш додаток має багато залежностей, які можуть бути порушені після оновлення. Таким чином ви можете відстежувати прогрес і не турбуватися про те, що додаток не збирається.

Side-by-side incremental. Це ідеальний вибір для веб-додатків. Оновлення з ASP.NET на ASP.NET Core вимагає багато роботи, а іноді і ручного рефакторингу (тому що ці дві технології дуже відрізняються). Бібліотеки класів часто використовуються разом з веб-додатками, тому ми надаємо такий тип оновлення і для бібліотек класів. Інкрементне оновлення розмістить проект .NET 6/7 поруч з вашим існуючим проектом .NET Framework і спрямує туди кінцеві точки, які реалізовані в проекті .NET 6/7, в той час як всі інші виклики будуть надсилатися до додатку .NET Framework. Таким чином, ви можете поєднати оновлення з розробкою нових функцій і перенести елементи на .NET 6/7 один за одним, не порушуючи роботу вашого додатку. Цей підхід був спочатку реалізований в інструменті Microsoft Project Migrations, ви можете розглядати Upgrade Assistant у Visual Studio як нову покращену і розширену версію Microsoft Project Migrations. Оновлення з .NET Core або .NET 5 до .NET 6/7 набагато простіше, ніж з .NET Framework, тому для таких випадків рекомендується використовувати опцію In-place.

 

У таблиці нижче ви можете знайти статус усіх типів оновлень за типами проектів.


In-place

Side-by-side

Side-by-side incremental

ASP.NET from .NET Framework

N/A

N/A

supported

ASP.NET from .NET Core, .NET5+

supported

N/A

N/A

WinForms from .NET Framework

supported

supported

N/A

WinForms from .NET Core, .NET5+

supported

N/A

N/A

WPF from .NET Framework

supported

supported

N/A

WPF from .NET Core, .NET5+

supported

N/A

N/A

Class Library from .NET Framework

supported

supported

supported

Class Library from .NET Core, .NET5+

supported

N/A

N/A

Console from .NET Framework

supported

supported

N/A

Console from .NET Core, .NET5+

supported

N/A

N/A

Xamarin to MAUI

in development

in development

N/A

MAUI from older versions

in development

N/A

N/A

UWP to WinUI

in development

in development

N/A

WinUI from older versions

in development

N/A

N/A

Azure Functions

in development

N/A

N/A

WCF to WCF Core

in development

N/A

N/A


Покрокове оновлення

1. Встановіть розширення Upgrade Assistant Visual Studio.

2. У Visual Studio в Solution Explorer натисніть правою кнопкою миші на проекті, який ви хочете оновити, і виберіть Upgrade.

3. Ви побачите головну сторінку з кількома варіантами оновлення.

Який варіант вибрати, описано в різних типах оновлень.

4. Для цього прикладу я обираю In-place. Side-by-side буде дуже схожим з кількома додатковими кроками. Додаткові можливості side-by-side incremental описані в попередньому пості в блозі.

 

5. Потім вам потрібно вибрати фреймворк, на який ви хочете перейти. Інструмент запропонує лише ті варіанти, які мають сенс для вашого типу проекту. У моєму прикладі це бібліотека класів .NET Framework, тому він також запропонує .NET Standard.

Всі оновлення є прямими, тобто якщо ваш проект, наприклад, вже працює на .NET 6, буде запропоновано лише .NET 7 і новіші версії. Якщо на вашому комп’ютері не встановлено обраний SDK, вам буде запропоновано встановити його на наступному кроці. Просто перейдіть за посиланням і поверніться до оновлення після встановлення SDK. .NET Standard пропонується лише для бібліотек класів, які були орієнтовані на .NET Framework.

6. Настав час вибрати компоненти, які ви хочете оновити. Зрештою, вам потрібно буде оновити все, але якщо ви віддаєте перевагу поетапному оновленню, на цьому екрані ви можете вибрати, з чого ви хочете почати.

7. Після натискання кнопки Upgrade selection ви побачите хід оновлення і звіт після його завершення.

 

Підсумок

Тепер ви можете оновлювати свої .NET проекти прямо з Visual Studio.


Source



Posted on 15. June 2022

Announcing Rate Limiting for .NET

Оголошення обмеження швидкості для .NET

Ми раді оголосити про підтримку вбудованого обмеження швидкості як частини .NET 7. Обмеження швидкості забезпечує спосіб захисту ресурсів, щоб уникнути перевантаження вашої програми та підтримувати трафік на безпечному рівні.

Що таке обмеження швидкості?

Обмеження швидкості — це концепція обмеження кількості доступних ресурсів. Наприклад, ви знаєте, що база даних, до якої звертається ваша програма, може безпечно обробляти 1000 запитів на хвилину, але не впевнені, що вона може обробляти набагато більше. Ви можете встановити обмежувач швидкості у своїй програмі, який дозволяє 1000 запитів щохвилини та відхиляє будь-які інші запити, перш ніж вони зможуть отримати доступ до бази даних. Таким чином, обмежуючи швидкість вашої бази даних і дозволяючи вашій програмі обробляти безпечну кількість запитів без потенційних збоїв у вашій базі даних.

Існує кілька різних алгоритмів обмеження швидкості для керування потоком запитів. Ми розглянемо 4 з них, які будуть доступні в .NET 7.

Ліміт паралельності

Обмежувач паралельності лімітує кількість одночасних запитів, які можуть отримати доступ до ресурсу. Якщо ваш ліміт становить 10, то 10 запитів можуть отримати доступ до ресурсу одночасно, а 11-й запит буде заборонено. Після завершення запиту кількість дозволених запитів збільшується на 1, коли завершується другий запит, кількість збільшується на 2 тощо. Це робиться шляхом утилізації RateLimitLease, про який ми поговоримо пізніше.

Обмеження відра токенів

Відро токенів — це алгоритм, назва якого походить від опису того, як він працює. Уявіть, що є відро, наповнене до країв токенами. Коли надходить запит, він приймає токен і зберігає його назавжди. Через певний період часу хтось додає заздалегідь визначену кількість токенів назад у відро, ніколи не додаючи більше, ніж може вмістити відро. Якщо відро порожнє, коли надходить запит, запиту буде відмовлено в доступі до ресурсу.

Щоб навести більш конкретний приклад, припустімо, що відро може вмістити 10 токенів і щохвилини до відра додається 2 токени. Коли надходить запит, він приймає токен, тож у нас залишається 9, надходять ще 3 запити, і кожен приймає токен, залишаючи нам 6 жетонів, через хвилину ми отримуємо 2 нових токени, що значить, що у нас 8 токенів. Надходять 8 запитів і забирають решту токенів, залишаючи нам 0. Якщо надходить інший запит, йому не дозволяється отримати доступ до ресурсу, доки ми не отримаємо більше токенів, що відбувається щохвилини. Після 5 хвилин відсутності запитів у відрі знову будуть усі 10 токенів і більше не додаватимуться протягом наступних хвилин, поки наступні запити не візьмуть більше токенів.

Фіксований ліміт вікна

Алгоритм із фіксованим вікном використовує концепцію вікна, яке також буде використано в наступному алгоритмі. Вікно — це проміжок часу, протягом якого застосовано наше обмеження, перш ніж ми перейдемо до наступного вікна. У випадку фіксованого вікна перехід до наступного вікна означає скидання ліміту до вихідної точки. Уявімо, що є кінотеатр з одним залом, який може вмістити 100 осіб, а фільм іде 2 години. Коли починається фільм, ми дозволяємо людям шикуватися в чергу для наступного сеансу, який відбудеться через 2 години, до 100 людей дозволяється шикуватися в чергу, перш ніж ми скажемо їм повернутися іншим разом. Після завершення 2-годинного фільму черга від 0 до 100 людей може переміститися до кінотеатру, і ми відновлюємо чергу. Це те саме, що переміщення вікна в алгоритмі фіксованого вікна.

Ліміт розсувного вікна

Алгоритм розсувного вікна подібний до алгоритму фіксованого вікна, але з додаванням сегментів. Сегмент є частиною вікна, якщо ми візьмемо попереднє 2-годинне вікно та розділимо його на 4 сегменти, тепер у нас будуть 4 30-хвилинні сегменти. Існує також індекс поточного сегмента, який завжди вказуватиме на найновіший сегмент у вікні. Запити протягом 30-хвилинного періоду переходять у поточний сегмент, і кожні 30 хвилин вікно зсувається на один сегмент. Якщо під час сегмента, вікно якого проходить, були запити, вони оновлюються, і наш ліміт збільшується на цю суму. Якщо запитів не було, наш ліміт залишається незмінним.

 

Наприклад, скористаємося алгоритмом ковзного вікна з 3 сегментами по 10 хвилин і обмеженням на 100 запитів. Нашим початковим станом є 3 сегменти з нульовими показниками, і наш поточний індекс сегмента вказує на 3-й сегмент.

Протягом перших 10 хвилин ми отримуємо 50 запитів, усі вони відстежуються в 3-му сегменті (наш поточний індекс сегмента). Після того, як минуло 10 хвилин, ми пересуваємо вікно на 1 сегмент, також переміщуючи поточний індекс сегмента до 4-го сегмента. Усі використані запити в 1-му сегменті тепер знову додаються до нашого ліміту. Оскільки їх не було, наше обмеження становить 50 (оскільки 50 уже використовується в 3-му сегменті).

Протягом наступних 10 хвилин ми отримуємо ще 20 запитів, тож зараз у нас 50 у 3-му сегменті та 20 у 4-му сегменті. Знову ж таки, ми пересуваємо вікно через 10 хвилин, тому наш поточний індекс сегмента вказує на 5, і ми додаємо будь-які запити з сегмента 2 до нашого ліміту.

Через 10 хвилин ми знову ковзаємо вікно, цього разу, коли вікно ковзає, індекс поточного сегмента дорівнює 6, а сегмент 3 (той, що містить 50 запитів) тепер знаходиться за межами вікна. Тож ми повертаємо 50 запитів і додаємо їх до нашого ліміту, який тепер становитиме 80, оскільки сегмент 4 все ще використовує 20.

API RateLimiter

Представляємо новий пакет nuget у .NET 7 System.Threading.RateLimiting!

Цей пакет містить примітиви для написання обмежувачів швидкості, а також надає кілька вбудованих алгоритмів, які зазвичай використовуються. Основним типом є абстрактний базовий клас RateLimiter.

RateLimiter містить Acquire і WaitAsync як основні методи для отримання дозволів на ресурс, який охороняється. Залежно від програми, захищеному ресурсу може знадобитися отримати більше 1 дозволу, тому обидва Acquire та WaitAsync приймають необов’язковий параметр permitCount. Acquire— це синхронний метод, який перевіряє, чи достатньо дозволів доступно чи ні, і повертає RateLimitLease, який містить інформацію про те, чи успішно ви отримали дозволи чи ні. WaitAsync схожий на, Acquire за винятком того, що він може підтримувати запити дозволів на постановку в чергу, які можна вилучити з черги в якийсь момент у майбутньому, коли дозволи стануть доступними, тому він асинхронний і приймає необов’язковий параметр CancellationToken дозволу скасування запиту в черзі .

 

RateLimitLease має властивість IsAcquired, яка використовується, щоб перевірити, чи були отримані дозволи. Крім того, RateLimitLease може містити такі метадані, як пропонований період повторної спроби після невдачі передачі (це буде показано в наступному прикладі). Нарешті, RateLimitLease є одноразовим і має бути утилізований після завершення коду з використанням захищеного ресурсу. Утилізація дозволить RateLimiter оновити свої ліміти на основі кількості отриманих дозволів. Нижче наведено приклад використання RateLimiter для спроби отримати ресурс з 1 дозволом.

У наведеному вище прикладі ми намагаємося отримати 1 дозвіл за допомогою синхронного методу Acquire. Ми також використовуємо using, щоб переконатися, що ми позбавляємося передачі, коли закінчимо з ресурсом. Потім перевіряється lease , щоб побачити, чи було отримано дозвіл, який ми запитували, якщо так, ми можемо використовувати захищений ресурс, інакше ми можемо захотіти мати журнал або обробку помилок, щоб повідомити користувача або програму, що ресурс не використовувався через досягнення обмеження швидкості.

 

Інший спосіб спроби отримати дозвіл – це WaitAsync. Цей метод дозволяє поставити дозволи в чергу та чекати, поки дозволи стануть доступними, якщо вони такими не є. Давайте покажемо інший приклад, щоб пояснити концепцію черги.

Тут ми показуємо наш перший приклад використання однієї з вбудованих реалізацій обмеження швидкості, ConcurrencyLimiter. Ми створюємо обмежувач із максимальним лімітом дозволів 2 і лімітом черги 2. Це означає, що в будь-який час можна отримати максимум 2 дозволи, і ми дозволяємо ставити виклики WaitAsync в чергу до 2 загальних запитів на дозволи.

Параметр queueProcessingOrder визначає порядок обробки елементів у черзі, це може бути значення QueueProcessingOrder.OldestFirst( FIFO ) або QueueProcessingOrder.NewestFirst( LIFO ). Одна цікава поведінка, на яку слід звернути увагу, полягає в тому, що використання QueueProcessingOrder.NewestFirst, коли черга заповнена, завершить найстаріші виклики WaitAsync в черзі з помилкою RateLimitLease, доки в черзі не залишиться місце для найновішого елемента черги.

У цьому прикладі 2 потоки намагаються отримати дозволи. Якщо потік 1 запускається першим, він успішно отримає 2 дозволи, а WaitAsync у потоці № 2 буде поставлено в чергу в очікуванні того, що  RateLimitLease буде видалено в потоці 1. Крім того, якщо інший потік намагається отримати дозволи за допомогою або Acquire або, WaitAsync він негайно отримає властивість RateLimitLease  з властивістю IsAcquired, що дорівнює false, оскільки permitLimit і queueLimit вже використано.

Якщо потік 2 виконується першим, він негайно отримає RateLimitLease з IsAcquired рівним true, а коли потік 1 виконується наступним (припускаючи, що lease в потоці 2 ще не скасовано), він синхронно отримає a RateLimitLease з властивістю IsAcquired, що дорівнює false, оскільки Acquire не ставить в чергу, і permitLimit використовується викликом WaitAsync.

 

Поки що ми бачили ConcurrencyLimiter, є ще 3 обмежувачі, які ми надаємо в комплекті. TokenBucketRateLimiter, FixedWindowRateLimiter, і SlidingWindowRateLimiter – всі вони реалізують абстрактний клас ReplenishingRateLimiter, який в свою чергу реалізує RateLimiter. ReplenishingRateLimiter вводить метод TryReplenish, а також кілька властивостей для спостереження за загальними налаштуваннями обмежувача. TryReplenish буде пояснено після демонстрації кількох прикладів цих обмежувачів швидкості.

Тут ми показуємо TokenBucketRateLimiter, він має трохи більше опцій, ніж ConcurrencyLimiter. ReplenishmentPeriod вказує як часто нові токени(така ж концепція, що й дозволи, лише краща назва в контексті сегмента токенів) додаються назад до ліміту. У цьому прикладі tokensPerPeriod - 1, а replenishmentPeriod - 5  секунд, тому кожні 5 секунд 1 маркер додається назад до максимуму 5 в tokenLimit. І, нарешті, в autoReplenishment встановлено значення true, що означає, що обмежувач створить внутрішній елемент для обробки поповнення маркерів кожні 5 секунд Timer.

 

Якщо autoReplenishmentвстановлено значення false, розробник повинен викликати TryReplenish в обмежувачі. Це корисно, коли ви керуєте кількома екземплярами ReplenishingRateLimiter та бажаєте зменшити навантаження, створивши один екземпляр Timer і самостійно керуючи викликами поповнення, замість того, щоб кожен обмежувач створював Timer.

FixedWindowRateLimiter має параметр window, який визначає, скільки часу потрібно для оновлення вікна.

У SlidingWindowRateLimiter є параметр segmentsPerWindow, який окрім window визначає кількість сегментів і частоту ковзання вікна.

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

У цьому прикладі ми обмежуємо швидкість HttpClient, і якщо нам не вдається отримати запитуваний дозвіл, ми хочемо повернути невдалий http-запит із кодом статусу 429 (забагато запитів), замість того, щоб надсилати HTTP-запит до нашого вихідного ресурсу. Крім того, відповіді 429 можуть містити заголовок «Retry-After», який повідомляє споживачеві, коли повторна спроба може бути успішною. Ми досягаємо цього шляхом пошуку метаданих про RateLimitLease використовуючи TryGetMetadata та MetadataName.RetryAfter. Ми також використовуємо TokenBucketRateLimiter, тому що він може обчислити приблизну кількість запитаних токенів, оскільки він знає, як часто він поповнює токени. У той час як у ConcurrencyLimiter не було б можливості дізнатися, коли дозволи стануть доступними, тому він не надавав би жодних метаданих RetryAfter.

MetadataName це статичний клас, який надає пару попередньо створених екземплярів MetadataName, MetadataName.RetryAfter який ми щойно бачили, який введено як MetadataName, і MetadataName.ReasonPhrase, який введено як MetadataName. Існує також статичний метод MetadataName.Create(string name) для створення власних строго типізованих іменованих ключів метаданих. RateLimitLease.TryGetMetadata має 2 перевантаження, одне для строго типізованого MetadataName, яке має параметр out T, а інше приймає рядок для назви метаданих і має параметр out object.

 

Давайте тепер подивимося на ще один API, який представляється для допомоги у більш складних сценаріях, PartitionedRateLimiter!

PartitionedRateLimiter

Також міститься в пакеті nuget System.Threading.RateLimiting PartitionedRateLimiter. Це абстракція, яка дуже схожа на клас RateLimiter, за винятком того, що вона приймає екземпляр TResource як аргумент для своїх методів. Наприклад, Acquire зараз: Acquire(TResource resourceID, int permitCount = 1). Це корисно для сценаріїв, коли ви можете змінити поведінку обмеження швидкості TResource залежно від того, що передано. Це може бути щось на кшталт незалежних обмежень паралельності для різних TResource або складніших сценаріїв, як-от групування X і Y під однаковим обмеженням одночасності, але мають W і Z під обмеженням сегмента токенів.

 

Щоб допомогти із звичайним використанням, ми включили спосіб побудови переходу

PartitionedRateLimiterPartitionedRateLimiter.Create(…)

PartitionedRateLimiter.Create має 2 параметри загального типу, перший представляє тип ресурсу, який також буде TResource у поверненому PartitionedRateLimiter. Другий загальний тип — це тип ключа розділу, у наведеному вище прикладі ми використовуємо MyPolicyEnum як тип ключа. Ключ використовується для розрізнення групи екземплярів TResource з однаковим обмежувачем, який ми називаємо розділом. PartitionedRateLimiter.Create приймає Func>, який ми називаємо розділювачем. Ця функція викликається кожного разу, коли з функцією PartitionedRateLimiter взаємодіють через Acquire або  WaitAsync, і функція повертає RateLimitPartition. RateLimitPartition містить метод Create, за допомогою якого користувач визначає, який ідентифікатор матиме розділ і який обмежувач буде пов’язаний із цим ідентифікатором.

У нашому першому блоці коду вище ми перевіряємо ресурс на рівність із “Policy1”, якщо вони збігаються, ми створюємо розділ із ключем MyPolicyEnum.One і повертаємо фабрику для створення власного RateLimiter. Обмежувач викликається один раз, а потім обмежувач швидкості кешується, тому майбутні доступи до ключа MyPolicyEnum.One використовуватимуть той самий екземпляр обмежувача швидкості.

Дивлячись на першу умову else if, ми так само створюємо розділ, коли ресурс дорівнює «Policy2», цього разу ми використовуємо зручний метод CreateConcurrencyLimiter для створення ConcurrencyLimiter. Ми використовуємо новий ключ розділу MyPolicyEnum.Two для цього розділу та вказуємо параметри для згенерованого ConcurrencyLimiter. Тепер кожен Acquire або WaitAsync для “Policy2” використовуватиме той самий екземпляр ConcurrencyLimiter.

Наша третя умова стосується нашого ресурсу «Адміністратор», ми не хочемо обмежувати наших адміністраторів, тому ми використовуємо, CreateNoLimiter які не матимуть жодних обмежень. Ми також призначаємо ключ розділу MyPolicyEnum.Admin для цього розділу.

Нарешті, у нас є запасний варіант для всіх інших ресурсів, щоб використовувати екземпляр TokenBucketLimiter, і ми призначаємо ключ MyPolicyEnum.Default цьому розділу. Будь-який запит до ресурсу, який не покривається нашими if умовами, використовуватиме TokenBucketLimiter. Загалом доцільно мати резервний обмежувач без Noop, якщо ви не охопили всі умови або не додали нову поведінку до своєї програми в майбутньому.

 

У наступному прикладі давайте об’єднаємо PartitionedRateLimiter з нашим попередньо налаштованим HttpClient. Ми будемо використовувати HttpRequestMessage як наш тип ресурсу для PartitionedRateLimiter, який є типом, який ми отримуємо в методі SendAsync від DelegatingHandler. І string для нашого ключа розділу, оскільки ми збираємося розділяти на основі шляхів url.

Придивившись до наведеного вище прикладу PartitionedRateLimiter, ми спочатку перевіряємо локальний хост. Ми вирішили, що якщо користувач виконує дії локально, ми не хочемо обмежувати його, він не використовуватиме вихідний ресурс, який ми намагаємося захищати. Наступна перевірка більш цікава, ми дивимося на url-шлях і знаходимо будь-які запити до  кінцевої точки /api/. Якщо запит відповідає, ми захоплюємо частину шляху та створюємо розділ для цього конкретного шляху. Це означає, що будь-які запити до /api/apple/*  використовуватимуть один екземпляр нашого ConcurrencyLimiter, а будь-які запити до /api/orange/* використовуватимуть інший екземпляр нашого ConcurrencyLimiter. Це пояснюється тим, що ми використовуємо інший ключ розділу для цих запитів, тому наша фабрика обмежувачів створює новий обмежувач для різних розділів. І, нарешті, у нас є запасний ліміт для будь-яких запитів, які не призначені для локального хосту чи кінцевої точки/api/*.

Також показано оновлення RateLimitedHandler, яке тепер приймає PartitionedRateLimiter замість RateLimiter та переходить через request до виклику WaitAsync, інакше решта коду залишиться незмінною.

У цьому прикладі варто звернути увагу на кілька речей. Ми потенційно можемо створити багато розділів, якщо буде зроблено багато унікальних запитів /api/*, це призведе до збільшення використання пам’яті в нашому PartitionedRateLimiter. PartitionedRateLimiter повернутий з PartitionedRateLimiter.Create дійсно має певну логіку для видалення обмежувачів, якщо вони не використовувалися протягом деякого часу, щоб допомогти пом’якшити це, але розробники програм також повинні знати про створення непов’язаних розділів і намагатися уникати цього, коли це можливо. Крім того, ми маємо segments[2].Trim(‘/’) для нашого ключа розділу виклик Trim, щоб уникнути використання іншого обмежувача у випадках /api/apple і /api/apple/ оскільки вони створюють різні сегменти під час використання Uri.Segments. 

 

Користувацькі реалізації PartitionedRateLimiter також можна писати без використання методу PartitionedRateLimiter.Create. Нижче наведено приклад власної реалізації з використанням обмеження паралельності для кожного ресурсу int. Таким чином, ресурс 1 має свій власний ліміт, 2 має власний ліміт тощо. Це має перевагу в тому, що він є більш гнучким і потенційно ефективнішим за рахунок більшого обслуговування.

Ця реалізація має деякі проблеми, наприклад, ніколи не видаляє записи у словнику, не підтримує черги і викидає при доступі до метаданих, тому, будь ласка, використовуйте її як натхнення для реалізації власного кастомного PartitionedRateLimiter і не копіюйте без змін у свій код.

 

Тепер, коли ми розглянули основні API, давайте подивимося на проміжне програмне забезпечення RateLimiting в ASP.NET Core, яке використовує ці примітиви.

Проміжне програмне забезпечення RateLimiting

Це проміжне програмне забезпечення надається через пакет Microsoft.AspNetCore.RateLimiting NuGet. Основний шаблон використання полягає в тому, щоб налаштувати деякі політики обмеження швидкості, а потім приєднати ці політики до кінцевих точок. Політика — названа  Func>, що збігається з тим, що взяв метод PartitionedRateLimiter.Create, де TResource зараз є HttpContext і TPartitionKey все ще є визначений користувачем ключ. Існують також методи розширення для 4 вбудованих обмежувачів швидкості, коли ви хочете налаштувати один обмежувач для політики без потреби в різних розділах.

У цьому прикладі показано, як додати проміжне ПЗ, налаштувати деякі політики та застосувати різні політики до різних кінцевих точок. Починаючи згори, ми додаємо проміжне програмне забезпечення до нашого конвеєра проміжного програмного забезпечення за допомогою UseRateLimiter. Далі ми додаємо кілька політик до наших параметрів за допомогою зручних методів AddConcurrencyLimiter і AddNoLimiter для 2 політик, названих “get” і “admin” відповідно. Потім ми використовуємо метод AddPolicy, який дозволяє налаштовувати різні розділи на основі переданого ресурсу ( HttpContext для проміжного ПЗ). Нарешті, ми використовуємо цей метод RequireRateLimiting на наших різних кінцевих точках, щоб дозволити проміжному програмному забезпеченню обмеження швидкості знати, яку політику виконувати на якій кінцевій точці. (Зверніть увагу,що  використання RequireAuthorization на кінцевій точці /admin нічого не робить у цьому мінімальному прикладі, уявіть, що автентифікація та авторизація налаштовані)

 

Метод AddPolicy також має ще 2 перевантаження, які використовують IRateLimiterPolicy. Цей інтерфейс надає зворотний виклик OnRejected, той самий, що RateLimiterOptions  який я опишу нижче, і метод GetPartition, який приймає HttpContext як аргумент і повертає RateLimitPartition. Перше перевантаження AddPolicy приймає екземпляр IRateLimiterPolicy, а друге приймає реалізацію IRateLimiterPolicy як загальний аргумент. Загальний аргумент one використовуватиме впровадження залежностей для виклику конструктора та створення екземпляра IRateLimiterPolicy для вас.