Перший додаток на ASP.NET Core
Перший додаток на ASP.NET Core: .NET CLI, Visual Studio та JetBrains Rider
1. Контекст: Що таке "Створення проекту" насправді?
Коли ми створюємо проект, ми, по суті, генеруємо структуру папок і файлів, яка зрозуміла інструментам розробки (компілятору, IDE). Історично проекти .NET складалися з десятків конфігураційних файлів (.config, .csproj, скрипти збірки тощо). В епоху Minimal API все зведено до абсолютного мінімуму: одного файлу коду і одного файлу проекту.
Перш ніж ми пірнемо в написання коду, нам потрібно обрати "зброю" — інструмент, за допомогою якого ми будемо кувати наш код. У світі .NET є три основні шляхи:
- .NET CLI (Інтерфейс командного рядка) — вибір хакерів, фанатів Linux, macOS та прихильників автоматизації (CI/CD).
- Visual Studio — класичний, потужний, корпоративний вибір для користувачів Windows. "Все включено".
- JetBrains Rider — сучасна кросплатформена IDE (працює на Mac, Linux, Windows), яка стала стандартом де-факто для багатьох сеньйорів завдяки вбудованому ReSharper (штучному інтелекту для рефакторингу).
Ми навчимося використовувати всі три.
2. Шлях Ніндзя: Створення через .NET CLI
.NET CLI (Command Line Interface) — це фундамент. Навіть коли ви натискаєте кнопку Run у Visual Studio чи Rider, під капотом вони часто звертаються саме до цих консольних команд. Розуміння CLI робить вас незалежним від конкретної IDE (наприклад, ви легко зможете писати код у легковаговику VS Code або навіть у Vim).
Крок 1: Встановлення .NET SDK
Що нам потрібно? Нам потрібен SDK (Software Development Kit).
- .NET Runtime — це середовище виконання. Його встановлюють звичайні користувачі або на серверах, щоб просто запустити вже написану програму. Воно містить віртуальну машину (CoreCLR) і базові бібліотеки поліології.
- .NET SDK — це набір інструментів для розробника. Він включає в себе Runtime, але також компілятор (Roslyn), збирач (MSBuild), систему шаблонів та інструменти тестування. Нам потрібен саме SDK.
- Перейдіть на офіційний сайт завантаження .NET.
- Оберіть поточну LTS (Long Term Support) версію (наприклад, .NET 8).
- Після встановлення відкрийте 터мінал (Terminal на macOS/Linux або PowerShell на Windows) і перевірте, чи все працює:
dotnet --version
Очікуваний результат: ви побачите номер версії, наприклад, 8.0.200.
Крок 2: Декомпозиція команди dotnet new
CLI має вбудований генератор шаблонів. Коли ви пишете dotnet new, працює рушій скаффолдингу (scaffolding).
Створімо нову теку і перейдемо в неї:
mkdir MyAwesomeApi
cd MyAwesomeApi
Тепер магічна команда:
dotnet new web -n MinimalShowcase
Давайте розберемо, що ми щойно ввели:
dotnet— виклик головного виконуваного файлу CLI.new— команда генерації коду з шаблону. Командний рядок переглядає встановлені шаблони.web— найважливіший параметр. Це коротка назва шаблону "ASP.NET Core Empty". Він створює абсолютно порожній додаток Minimal API. (Існують інші шаблони:mvcдля класичних контролерів,blazorдля фронтенду,consoleдля консольних утиліт).-n MinimalShowcase— аргументname(назва). Якщо не вказати, назва проекту буде збігатися з назвою папки (MyAwesomeApi), але тут ми жорстко задали ім'я проекту.

Крок 3: Запуск сервера (Команда dotnet run)
Сервер готовий. Що далі? Запуск.
dotnet run
Коли ви натискаєте Enter, відбувається магія, що складається з кількох етапів:
- Restore: CLI перевіряє файл проекту (
.csproj) і завантажує всі відсутні NuGet-пакети з інтернету в локальний кеш комп'ютера. (Неявно викликаєтьсяdotnet restore). - Build: Викликається компілятор Roslyn. Ваш C# код перетворюється на Intermediate Language (IL) — байт-код. Якщо є синтаксичні помилки, процес зупиниться тут. (Неявно викликається
dotnet build). - Execute: Запускається .NET віртуальна машина, яка стартує сервер Kestrel.
В результаті ви побачите в консолі щось на кшталт:
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5032
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
Відкрийте браузер за вказаною адресою http://localhost:5032 і ви побачите магічні слова Hello World!.
dotnet run — це марнування часу. Використовуйте команду dotnet watch (або dotnet watch run). Вона запустить сервер, а потім буде стежити за змінами у ваших файлах. Щойно ви натиснете "Зберегти" у файлі Program.cs, сервер миттєво перезапуститься сам, або навіть застосує зміни без перезапуску (фіча відома як Hot Reload).3. Шлях Архітектора: Створення через Visual Studio 2022
Для багатьох розробників Visual Studio — це дім. Вона знімає з розробника когнітивне навантаження, запам'ятовуючи команди і надаючи візуальний інтерфейс.
Крок 1: Встановлення
- Перейдіть на сайт Visual Studio. Для навчання ідеально підходить версія Community, вона безкоштовна і повнофункціональна.
- При встановленні ви побачите вікно "Workloads" (Робочі навантаження). Це модулі. Обов'язково виберіть "ASP.NET and web development". Саме цей модуль містить всі шаблони і локальний веб-сервер IIS Express.
Крок 2: Процес створення (Візард)
- Запустіть Visual Studio. Натисніть "Create a new project".
- У пошуку зірвалася сотня шаблонів. Не губіться. Пишіть
ASP.NET Core Empty. Саме цей шаблон є синонімом командиdotnet new web. (Існує шаблонASP.NET Core Web API, але він набагато важчий: до нього входить Swagger, контролери та купа коду погоди(WeatherForecast). Для вивчення фундаменту нам потрібен "Empty"). - Оберіть назву та розтошування на диску.
- На наступному екрані (
Additional Information) найважливіші 체크бокси:- Framework: виберіть найновішу LTS версію (наприклад, .NET 8).
- Configure for HTTPS: за замовчуванням увімкнено. Увімкніть. Ваш локальний сервер створить самопідписаний сертифікат, щоб працювати безпечно.
- Do not use top-level statements: Залиште вимкненим! Ми обговорювали це раніше. Ми хочемо сучасний Minimal API стиль без класового шуму.

Крок 3: Запуск однією кнопкою (F5)
Натисніть зелену кнопку "Play" або клавішу F5 на клавіатурі.
У Visual Studio F5 означає "Start with Debugging". Вона не просто запустить програму, вона "причепить" до неї відладчик (Debugger). Ви зможете ставити точки зупинки (breakpoints) і перевіряти значення змінних у пам'яті "на льоту".
Браузер автоматично відкриється. Магія.
4. Шлях Кросплатформеника: Створення через JetBrains Rider
Rider став неймовірно популярним завдяки своїй неймовірній швидкості, ідеальному парсингу коду та тому факту, що він однаковий на Mac, Linux та Windows.
Особливості створення в Rider
Процес дуже схожий на Visual Studio, але інтерфейс трохи інший:
- На екрані вітання натисніть "New Solution".
- У лівому боковому меню знайдіть розділ
.NET / .NET Coreі оберіть Empty Web. (Це аналогASP.NET Core Empty). - Заповніть Solution Name.
- Зверніть увагу на поле "Project framework" — впевніться, що там обрана потрібна версія.
- Натисніть Create.
- У правому верхньому куті вікна Rider є панель запуску. Натисніть зелений жучок (Debug) або зелену стрілку (Run).
Завдяки вбудованому серверному терміналу внизу вікна, ви побачите ті ж самі логі Kestrel, що і при роботі з CLI.
5. Анатомія Проекту: Що всередині папки?
Незалежно від обраного інструменту, ви отримали папку. Давайте подивимося на структуру через лінзу розробника.
Ми розберемо кожен з ключових файлів. Інженер має знати свої інструменти.
Вузол 1: .csproj (C-Sharp Project)
Цей файл — це XML-документ, який говорить компілятору і системі збірки (MSBuild), що це за проект і які математичні/фізичні обмеження він має. Відкрийте його у звичайному блокноті. Ви здивуєтеся, який він короткий:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
Що тут цікавого?
Sdk="Microsoft.NET.Sdk.Web"— саме цей атрибут говорить системі: "Це не консольний додаток. Це не бібліотека. Це ВЕБ-ДОДАТОК". Цей SDK автоматично підключає сотні dll-файлів, пов'язаних з Kestrel, HTTP, роутингом. Якби ми змінили його наMicrosoft.NET.Sdk, наш веб-сервер перестав би компілюватися.<TargetFramework>net8.0</TargetFramework>— версія платформи. Змінивши цифру 8 на 7 і виконавшиdotnet restore, ви зміните фундамент усього додатку.<Nullable>enable</Nullable>— увімкнення жорсткої перевірки на можливіnullзначення під час компіляції (захист від NullReferenceException).<ImplicitUsings>enable</ImplicitUsings>— "секрет" того, чому фійлProgram.csтакий чистий. Як обговорювалося в Модулі 1, це автоматично ховає імпорти системних бібліотек.
.csproj — керування зовнішніми бібліотеками (NuGet-пакетами). Коли ви додаєте нову бібліотеку через консоль, наприклад dotnet add package Newtonsoft.Json, у цей файл автоматично розширюється вузлом <ItemGroup>, який міститиме <PackageReference Include="Newtonsoft.Json" Version="..." />. Саме завдяки цьому dotnet restore знає, які пакети необхідно завантажити перед компіляцією.
У Visual Studio ці залежності також відображаються у вузлі Dependencies (Залежності) в Оглядачі рішень (Solution Explorer).Вузол 2: appsettings.json
У будь-якому додатку є "секрети" або "конфігурації". Наприклад, адреса бази даних (Connection String), рівні логування або налаштування пошти. "Харакірі" для програміста — вписувати ці налаштування безпосередньо в код C# (hardcoding).
Для цього існує appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Чому їх два? (appsettings.json та appsettings.Development.json)
ASP.NET Core побудований з розумінням "Середовищ" (Environments). У вас є середовище розробки (у вас на комп'ютері) і середовище продакшену (на бойовому сервері в датацентрі). Фреймворк налаштований так: він спочатку читає appsettings.json, а потім зверху на нього накладає зміни з appsettings.Development.json (якщо ви зараз у режимі розробки). Наприклад, ви можете логувати кожну деталь у дев-режимі, але в продакшені логувати тільки критичні помилки.
Вузол 3: Properties/launchSettings.json
Цей файл існує ЛИШЕ ДЛЯ РОЗРОБКИ. Він НІКОЛИ не йде на бойовий сервер. Він пояснює вашій локальній середі (Visual Studio, Rider або dotnet run), як саме стартувати Kestrel.
{
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5032",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
...
}
}
"commandName": "Project"— означає, що запускатиметься Kestrel безпосередньо."launchBrowser": true— коли код скомпілюється, IDE сама відкриє Google Chrome."applicationUrl": "http://localhost:5032"— порт, який слухатиме наш локальний сервер. За замовчуванням він генерується випадковим чином при створенні проекту (щоб уникнути конфліктів портів)."ASPNETCORE_ENVIRONMENT": "Development"— саме ця системна змінна вчиняє магію і змушує ASP.NET читатиappsettings.Development.json.
6. Глибока Анатомія: Розтин Program.cs
Ось він, святий Грааль усього проекту. Всього 4 рядки. Але за кожним рядком — тисячі годин інженерної роботи Microsoft. Ми розкладемо цей код на молекули.
Код виглядає так:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
Рядок 1: Створення Будівельника (Builder Pattern)
var builder = WebApplication.CreateBuilder(args);
WebApplicationBuilder із заздалегідь налаштованими стандартними значеннями. Приймає масив рядків, переданий з командного рядка під час запуску програми. Повертає об'єкт WebApplicationBuilder.Аналогія: Ви наймаєте генерального підрядника для будівництва будинку.
Підрядник (це наш builder) не просто стоїть. Метод CreateBuilder(args) виконує гігантський обсяг роботи ще до того, як ви почнете писати код. Під "капотом" він:
- Завантажує змінні середовища ОС (наприклад, PATH або системні секрети).
- Завантажує файл
appsettings.json(де ми були хвилину тому). - Налаштовує вбудований Dependency Injection контейнер (наш склад з інструментами — ми детально поговоримо про нього в наступному модулі).
- Налаштовує систему логування, щоб вона одразу вміла писати логи в консоль кольоровими буквами.
- Налаштовує веб-сервер Kestrel і читає
launchSettings.json.
На цьому етапі ви втручаєтеся і можете сказати підряднику: "Гей, побудуй мені також додатковий басейн (додай підключення до Бази Даних) або постав сигналізацію (додай систему Автентифікації)". Ми робимо це до написання builder.Build().
Що таке args? Якщо ви запустите програму в консолі командою dotnet run -- --port 8080, масив args передасть ці додаткові параметри нашому генеральному підряднику, щоб він міг переконфігурувати програму "на льоту".
Рядок 2: Затвердження плану (Build)
var app = builder.Build();
Після того, як ви надали підряднику всі інструкції, ви кажете: "Будуй". Коли викликається Build(), контейнер об'єктів заморожується. Це операція в одну сторону (One-way operation). З цього моменту ви більше не можете додавати нові "фундаментальні сервіси" в архітектуру.
Натомість, вам повертається об'єкт app — це екземпляр класу WebApplication.
IApplicationBuilder (для налаштування middleware пайплайну) та IEndpointRouteBuilder (для налаштування маршрутизації).Аналогія: Будинок здано в експлуатацію. Стіни стоять, світло підведено. Тепер ви (як власник app) розставляєте меблі, визначаєте правила (хто першим заходить, де знімати взуття), тобто встановлюєте Middleware і Маршрути.
Рядок 3: Маршрутизація (Routing) і Делегати. Ваша перша бізнес-логіка
app.MapGet("/", () => "Hello World!");
Тут ми навчаємо наш веб-сервер спілкуватися.
Ми викликаємо метод MapGet.
IEndpointRouteBuilder. Додає новий кінцевий вузол (Endpoint), який реагуватиме виключно на HTTP запити з методом GET, якщо URL в браузері відповідатиме заданому pattern.
Параметри:pattern- шаблон шляху, рядок. Наприклад"/api/users".handler- логіка обробки. Зазвичай передається як анонімна функція (лямбда-вираз).
Коли клієнт відкриває браузер і набирає адресу (наприклад, http://localhost:5032/), браузер неявно робить HTTP-запит типу GET. Сервер Kestrel ловить цей запит, перетворює його на об'єкт HttpContext і передає в рушій Маршрутизації (Router). Рушій дивиться у свою внутрішню карту (Map):
- "Є в мене щось на метод GET для шляху
/(кореневий каталог)?" - "Так, є! Ось вона, мета-функція (лямбда)
() => "Hello World!""
Сервер заходить всередину лямбда-виразу. Лямбда-вираз відпрацьовує і повертає звичайний C# string (рядок). Сервер достатньо розумний, щоб сказати:
"Ага, клієнту повертається рядок. Я сам оберну це в правильний HTTP-відповідь! Я сам додам статус-код 200 OK. Я сам додам заголовок Content-Type: text/plain!"
І ми бачимо результат на екрані.
!CAUTIONЩо буде, якщо змінити код? Спробуйте змінити
MapGetнаMapPost. Запустіть сервіс і перезавантажте сторінку браузера. Браузери через адресний рядок вміють відправляти тільки GET-запити. Сервер побачить GET-запит на "/", подивиться у карту і побачить "У мене є POST на '/', але немає GET на '/'". Сервер поверне вам сумну помилку 404 Not Found (або 405 Method Not Allowed, залежно від конфігурації маршрутизатора). Це доводить, що ASP.NET жорстко контролює HTTP-методи.
Рядок 4: Безкінечний цикл очікування
app.Run();
Сервер — це програма, яка в ідеалі ніколи не закінчується. Якби не метод Run(), програма просто дійшла б до 4-го рядка і завершилася б в ту саму мілісекунду, і вікно консолі закрилося б.
Run() — це, спрощено кажучи, велетенський безкінечний цикл while (true), який блокує основний потік (Thread) програми і змушує Kestrel затамувати подих і слухати мережеву плату комп'ютера. Він прийматиме нові й нові підключення, доки ви не натиснете Ctrl+C в консолі.
Код Run() розроблений так, що він асинхронно чекає подію закінчення процесу CancellationToken.
7. Практичні вправи: Тренуємо м'язи кодування
Замість того, щоб йти далі, закріпіть розуміння самостійними діями. Зробіть це прямо зараз у своєму проекті.
- Завдання 1: Змініть порт. Відкрийте
Properties/launchSettings.jsonі змініть порт з 5032 на8080. Збережіть і натиснітьdotnet run. Відкрийте в браузеріhttp://localhost:8080. - Завдання 2: Мульти-роутинг. Додайте підрядком ще один ендпоінт. Перед
app.Run(), додайте:Перезапустіть сервер. Зайдіть наapp.MapGet("/about", () => "It's me, Minimal Server!");/і на/about. Що відбувається? Поспостерігайте за гнучкістю. - Завдання 3: Метод розширення. Змініть текст "Hello World!" на "Привіт, Світ!". Зверніть увагу на кодування тексту в браузері. Чи правильно відображаються літери? (Це перевірка того, як автоматично встановлюється кодування UTF-8).
8. Експертний розділ: Чи є в Minimal API багатопоточність?
Часте питання від спеціалістів, які переходять з Node.js чи PHP.
У Node.js ми маємо єдиний потік виконання (Single Thread Event Loop). Якщо один HTTP запит виконає важку математичну функцію while(true), вебсервер "повисне", і ніхто інший не зможе достукатися до сайту.
ASP.NET Core (включно з Minimal API) є багатопоточним і використовує Асинхронну модель на основі пулу потоків (Thread Pool).
Якщо одночасно прийде 100 запитів на сторінку /, ASP.NET візьме з "пулу потоків" 100 вільних робітників, і вони ВСІ паралельно виконають вашу лямбду.
Це величезна перевага в системній продуктивності. Але це вимагає від вас бути уважними, якщо ви намагаєтесь записати дані в загальний для всіх ресурс (наприклад, у спільний статичний масив) — ми поговоримо про цю проблему (Thread-Safety) в майбутньому модулі.
9. Підсумок модуля
- Ми навчились створювати проекти декількома способами. CLI дає контроль. Visual Studio дає підтримку "в один клік", а Rider дає гнучкість кросплатформеності.
- Проект Minimal API структурно примітивний. Головні кити:
.csprojдля компілятора,appsettings.jsonдля секретів і змінних,Program.csдля бізнес-логіки. - 4 рядки
Program.cs— це складний конвеєр:CreateBuilderготує середовище з сотнями налаштувань.Buildфіксує фундамент архітектури і створює додаток.MapGetвизначає правила переадресації.Runзапускає нескінченний процес-слухач Kestrel.
Важко повірити, скільки інженерії приховано за простотою. У наступному модулі ми порушимо цю гармонію, "розкриємо" наш Builder і розберемо одну з найбільш геніальних філософій сучасного програмування — Dependency Injection (впровадження залежностей).
Перевірка знань
Якщо тест не завантажується, дайте відповідь на ці питання самостійно:
- Який файл відповідає за параметри під час запуску додатку (порт, браузер), і чому його не варто відправляти на Production сервер?
- В чому принципова різниця між
builderтаapp? Чому Microsoft не об'єднали це в один об'єкт? - Чому сервер видає помилку, якщо ми використовуємо
MapPost("/", ...)і звертаємось до сайту через рядок браузера?
Вступ до ASP.NET та еволюція фреймворку
Глибоке занурення в анатомію ASP.NET Core, історію його розвитку, архітектуру Kestrel та причини переходу до Minimal API.
WebApplication, Builder та Dependency Injection
Глибинний розбір патерну Builder в ASP.NET Core, розуміння архітектури Dependency Injection, методів розширення та життєвого циклу додатка.