Minimal API

Статичні файли в ASP.NET Core

Будь-який сучасний веб-додаток, окрім динамічних даних (JSON з бази даних), потребує віддавати клієнту так звані статичні файли. Це HTML-сторінки, CSS-стилі, JavaScript-скрипти, зображення (PNG, JPG) та шрифти, які лежать на диску сервера і не змінюються при кожному запиті.

Статичні файли в ASP.NET Core

Будь-який сучасний веб-додаток, окрім динамічних даних (JSON з бази даних), потребує віддавати клієнту так звані статичні файли. Це HTML-сторінки, CSS-стилі, JavaScript-скрипти, зображення (PNG, JPG) та шрифти, які лежать на диску сервера і не змінюються при кожному запиті.

За замовчуванням ASP.NET Core не віддає жодних файлів з міркувань безпеки. Уявіть, якби користувач міг написати GET /appsettings.json і завантажити ваші паролі від бази даних! Тому роздачу файлів потрібно явно вмикати.

У цьому розділі ми розглянемо традиційний підхід до роботи зі статичними файлами за допомогою Middleware-компонентів.

Тека wwwroot (Web Root)

В ASP.NET Core існує спеціальне місце для зберігання статичних файлів, до яких матиме доступ зовнішній світ — це папка wwwroot, яка знаходиться в корені вашого проєкту.

Структура проєкту зазвичай виглядає так:

MyProject/
├── Program.cs
├── appsettings.json
└── wwwroot/
    ├── css/
    │   └── style.css
    ├── js/
    │   └── app.js
    ├── images/
    │   └── logo.png
    └── index.html

Все, що лежить поза wwwroot, клієнт ніколи не зможе завантажити через браузер (якщо ви спеціально це не дозволите кодом).

Middleware UseStaticFiles

Щоб дозволити серверу віддавати файли з wwwroot, потрібно додати до конвеєра обробки запитів StaticFileMiddleware. Це робиться за допомогою методу UseStaticFiles().

Program.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Вмикаємо роздачу статичних файлів з папки wwwroot
app.UseStaticFiles();

app.MapGet("/", () => "Hello World!");

app.Run();

Анатомія коду:

  • Коли приходить запит GET /css/style.css, Middleware перевіряє, чи існує файл MyProject/wwwroot/css/style.css.
  • Якщо файл є, він відразу завантажується клієнту з правильним HTTP-заголовком Content-Type (наприклад, text/css для .css або image/png для .png), і наступні Middleware не викликаються.
  • Якщо файлу немає, запит передається далі по конвеєру (наприклад, до роутингу, який поверне маршрут "/").
Порядок Middleware дуже важливий! Зверніть увагу: ми викликаємо UseStaticFilesпередMapGet("/"). Це означає, що спочатку ми шукаємо файл на диску, а вже потім шукаємо програмовані маршрути. Зазвичай статику ставлять якомога вище у пайплайні, відразу після перенаправлення на HTTPS, щоб швидко віддавати зображення та уникати запуску логіки аутентифікації для файлів (якщо вони публічні).

Файли за замовчуванням: UseDefaultFiles

Що відбувається, коли користувач просто вводить вашу адресу https://mysite.com/ (кореневий маршрут)? Зазвичай, він очікує побачити головну HTML-сторінку.

Щоб сервер автоматично шукав index.html або default.html (коли шлях є просто назвою папки), потрібно використати метод UseDefaultFiles().

Program.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Змушує запити до папок шукати в них файли за замовчуванням (наприклад, index.html)
app.UseDefaultFiles();
// Віддає ці файли
app.UseStaticFiles();

app.Run();

Анатомія коду:

  1. Запит: GET /
  2. UseDefaultFiles перехоплює його, бачить, що це перегляд папки, шукає в wwwroot файл index.html і внутрішньо переписує (rewrite) запит з / на /index.html.
  3. Запит іде далі.
  4. UseStaticFiles бачить запит /index.html і, оскільки файл існує в wwwroot, віддає його.

Важливо: UseDefaultFiles повинен викликатися перед UseStaticFiles. Перший переписує URL, а другий фізично віддає файл.

За замовчуванням UseDefaultFiles шукає такі імена файлів у вказаному порядку:

  • default.htm
  • default.html
  • index.htm
  • index.html

Перегляд каталогів: UseDirectoryBrowser

Іноді ви створюєте публічний архів документів (наприклад, /downloads/), і хочете, щоб користувачі бачили список усіх файлів у папці, як у провіднику Windows, якщо вони переходять за цією адресою.

З міркувань безпеки це вимкнено за замовчуванням. Щоб увімкнути, використовують UseDirectoryBrowser().

Program.cs
var builder = WebApplication.CreateBuilder(args);

// Потрібно явно додати сервіс перегляду директорій
builder.Services.AddDirectoryBrowser();

var app = builder.Build();

app.UseStaticFiles();
app.UseDirectoryBrowser(); // Дозволяє бачити список файлів

app.Run();

Якщо тепер зайти на http://localhost:5000/images/, браузер покаже красиву HTML-таблицю зі списком ресурсів в папці.

UseFileServer: все в одному

Оскільки UseDefaultFiles, UseStaticFiles та UseDirectoryBrowser часто використовуються разом і їх порядок важливий, фреймворк надає зручний метод UseFileServer, який поєднує в собі всі три!

Замість цього:

app.UseDefaultFiles();
app.UseStaticFiles();
// app.UseDirectoryBrowser();

Ви можете написати так:

Program.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Вмикає Default Files + Static Files. (Directory Browser вимкнено за замовчуванням).
app.UseFileServer();

app.Run();

Щоб дозволити ще й перегляд каталогів, потрібно передати FileServerOptions:

Program.cs
app.UseFileServer(new FileServerOptions
{
    EnableDirectoryBrowsing = true
});

Роздача файлів з інших папок

Що, як вам потрібно роздавати зображення з папки D:\MyImages, яка лежить поза вашим проєктом, але ви хочете, щоб вони були доступні за URL /pictures? Це робиться за допомогою налаштування опцій (Options) для Middleware.

Program.cs
using Microsoft.Extensions.FileProviders;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Стандартна папка wwwroot (шлях /)
app.UseStaticFiles();

// Кастомна папка десь на диску (шлях /pictures)
app.UseStaticFiles(new StaticFileOptions
{
    // Фізичний шлях до папки на сервері
    FileProvider = new PhysicalFileProvider(@"D:\MyImages"),
    // URL префікс для доступу через браузер
    RequestPath = "/pictures"
});

app.Run();

Анатомія коду:

  • Якщо браузер запитує GET /styles.css, спрацює перший UseStaticFiles і шукатиме файл у wwwroot/styles.css.
  • Якщо браузер запитує GET /pictures/cat.jpg, перший Middleware його пропустить, але спрацює другий UseStaticFiles. Він зрозуміє префікс /pictures, відріже його, і почне шукати cat.jpg у фізичній папці D:\MyImages\cat.jpg.

Практичні завдання

Запуск статичного сайту

  1. В корені вашого проєкту (поруч з Program.cs) створіть папку wwwroot.
  2. У wwwroot створіть файл index.html з текстом <h1>Ласкаво просимо!</h1>.
  3. Налаштуйте пайплайн за допомогою одного єдиного рядка коду, щоб при запуску додатку і переході в корінь (/), автоматично відкривався ваш index.html.
Copyright © 2026