5. diel - Pohľad, middleware a routovanie v ASP.NET Core MVC
V minulej lekcii, Prvá webová aplikácia v ASP.NET Core MVC , sme začali s tvorbou našej prvej webovej aplikácie v ASP.NET Core MVC, ktorou je generátor náhodných čísel.
V dnešnom ASP.NET Core tutoriále si do našej prvej webovej aplikácie v ASP.NET Core MVC doplníme pohľad, middleware a routovanie.
View
V našej aplikácii nám ešte chýba šablóna (pohľad), v ktorej výstup zobrazíme užívateľovi.
Pojmy šablóna a pohľad sa budú v kurze zamieňať, bude tým myslený vždy pohľad.
View (pohľad) najjednoduchšie pridáme priamo z príslušného kontroléra.
Klikneme pravým tlačidlom kamkoľvek do metódy Index()
a
zvolíme Add View...:
V novo otvorenom okne vyberieme Razor View - Empty a potvrdíme. Pohľad sa bude volať rovnako ako metóda:
Po potvrdení vytvorenia sa nám vygeneruje HTML šablóna s nasledujúcim obsahom:
@* For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 *@ @{ }
Na začiatku vidíme komentár zapísaný medzi zavináčmi s hviezdičkami a blok pre C# kód začínajúci zavináčom a ohraničený zloženými zátvorkami. To je syntax tzv. Razor engine, ktorý slúži na vkladanie C# kódu do HTML. Existuje ešte niekoľko ďalších renderovacích enginov, ale takmer sa nepoužívajú.
Už vieme, že všetka logika by mala byť obsiahnutá v modeloch. V pohľadoch budeme C# používať iba na výpis hotových dát, ktoré sme z modelov získali. Razor direktív by v šablónach malo byť čo možno najmenej.
Základná štruktúra
Aktuálny obsah šablóny zmažeme a vytvoríme si validnú štruktúru HTML dokumentu:
<!DOCTYPE html> <html lang="cs"> <head> <meta charset="utf-8" /> <title>Online generátor náhodných čísel</title> </head> <body> </body> </html>
Ako môžeme vidieť, zatiaľ sa jedná o klasické HTML. Ak sme teda absolvovali základný kurz tvorby webových stránok, tak by nás tu nemalo nič prekvapiť. Stránke sme nastavili:
- jazyk na slovenčinu,
- kódovanie
UTF-8
a - titulok.
Telo stránky
Teraz už do šablóny doplníme samotný obsah v tele
<body>
. Stránka bude zobrazovať iba jeden nadpis a odsek s
vygenerovaným náhodným číslom:
<body> <h1>Náhodné číslo</h1> <p style="font-size: 2em;">@ViewBag.Cislo</p> </body>
Náhodné číslo vypisujeme z kolekcie ViewBag
, kam ho uložil
kontrolér. Ten ho získal z modelu, ktorý ho vygeneroval.
Základné Razor syntax
Ku kolekcii ViewBag
pristupujeme cez Razor direktívu
@
. Zakaždým, keď chceme v šablóne vykonať C# príkaz, ktorý
má do šablóny vložiť nejaký obsah, tak pred neho napíšeme zavináč
@
.
V prípade, keď potrebujeme vykonať:
- príkaz, ktorý nič nevracia,
- príkaz priradenia alebo
- po sebe viac príkazov naraz,
@
a je ohraničený zloženými zátvorkami
{}
. Takto by sme napríklad mohli vypísať druhú mocninu
vygenerovaného čísla s uložením výsledku do premennej:
<body> <h1>Náhodné číslo</h1> <p style="font-size: 2em;"> @{ int mocnina = ViewBag.Cislo * ViewBag.Cislo; @mocnina } </p> </body>
V pohľadoch by sa správne nemali takéto výpočty vyskytovať. Výpočty sa umiestňujú do v modeli av pohľade cez kontrolér sa iba odovzdávajú výsledky. Docieli sa tak lepšia prehľadnosť nášho kódu, keď bude väčšina logiky umiestnená iba v modeli.
Z bloku kódu môžeme vracať aj HTML elementy. Nasledujúca ukážka vygeneruje rovnaký HTML kód ako tá predchádzajúca:
<body> <h1>Náhodné číslo</h1> @{ int mocnina = ViewBag.Cislo * ViewBag.Cislo; <p style="font-size: 2em;"> @mocnina </p> } </body>
Tieto dve ukážky berme skutočne len ako ukážky. V našej aplikácii budeme pracovať s verziou vypisujúcou iba vygenerované náhodné číslo, nie jeho druhú mocninu.
URL adresa
Iste viete, že každá webová stránka je na internete identifikovaná svojou unikátnou URL adresou. Takáto URL adresa sa skladá predovšetkým z:
- doménového mena a
- cesty.
https://www.domena.cz/home/index
Časť www.domena.cz
je tu doménovým menom a časť
/home/index
je potom cestou. Doménové meno býva pre jeden web
väčšinou nemenné. Cesta sa však už pre každú stránku webu líši.
Práve cesta URL adresy totiž identifikuje konkrétnu stránku daného webu.
Cesta sa skladá z ľubovoľného množstva segmentov
oddelených lomítkom /
.
Vyššie zvolená adresa nebola zvolená náhodne. Keď sa pozrieme na jej
cestu /home/index
, tak tá zodpovedá štruktúre našej
aplikácie. V našej aplikácii máme kontrolér HomeController
,
ktorý má akciu Index()
. Uvedená cesta spĺňa všeobecne
používanú konvenciu riešiacu smerovanie (mapovanie) cesty
URL adresy na akcie kontrolérov v ASP.NET aplikáciách. Prvým segmentom je
vždy názov kontroléra, druhým je názov akcie daného kontroléra a zvyšné
segmenty potom slúžia ako prípadné parametre.
Middleware, spracovanie požiadaviek a routovanie
Keby sme našu aplikáciu teraz spustili (napr. klávesovou skratkou
Ctrl + F5), zobrazila by sa iba hláška "Hello World!" a
náš kontrolér by sa nespustil vôbec. Keďže sme pri vytváraní projektu
zvolili prázdnu šablónu, musíme HomeController
sami
nasmerovať, aby sa spustil ako predvolený.
Práve tomuto mechanizmu smerovania URL adries na kontrolérov alebo inej časti aplikácie sa hovorí routovanie.
Routovanie sa nastavuje v súbore Program.cs
, ktorého obsah
teraz vyzerá asi nasledovne:
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.Run();
Do tohto súboru budeme písať registrácia služieb a
väčšinu konfigurácií aplikácie, ktorej zostavenie
zaisťuje inštancia triedy WebApplicationBuilder
s metódou
Build()
. Ako si môžeme všimnúť, hláška "Hello World!" by sa
po spustení aplikácie zobrazila preto, že je tu v predvolenom stave pomocou
metódy MapGet()
nastavené smerovanie cesty /
na
vrátenie práve tohto reťazca.
Do súboru Program.cs
môžeme do zostavenej aplikácie ďalej
písať tzv. middleware. Middleware si v ASP.NET Core môžeme
predstaviť ako sériu filtrov, cez ktoré postupne putuje požiadavka od
užívateľa na server, kým sa nájde ten vhodný, ktorý ho spracuje. Majú
podobu rozširujúcich metód na inštanciu zostavenej
aplikácie (niektorým z vás pravdepodobne pripomenú návrhový vzor Chain
of responsibility, pretože sa reťazí).
Každý middleware v reťazci má iba obmedzenú a špecifickú
úlohu v spracovaní požiadavky - napr. prvá môže plniť len funkciu
loggeru, ďalší middleware bude hľadať nejakú cookie alebo autorizačný
token. A ak nenájde čo hľadá, vráti chybovú hlášku alebo používateľa
presmeruje. Napr. middleware UseFileServer()
nám umožní ako
odpoveď vrátiť statický obsah (skripty v Javascripte, obrázky, CSS súbory
atď.) nášho projektu a podobne.
V .NET 5.0 a starších verziách je kód súboru
Program.cs
vyčlenený do metód ConfigureServices()
a
Configure()
v súbore Startup.cs
. V metóde
ConfigureServices()
sa registrujú služby av metóde
Configure()
sa konfiguruje middleware na už zostavenej
aplikácii.
Routovanie na kontrolér
Budeme teda chcieť, aby sa používateľ hneď po spustení aplikácie
nasmeroval na kontrolér HomeController
a jeho akciu
Index()
. Zároveň budeme chcieť, aby všetky cesty spĺňali
vyššie uvedenú konvenciu, teda aby mali vzor
/nazev_kontroleru/nazev_akce
. Na to využijeme middleware
MapControllerRoute()
, ktorý sa stará o napojenie cesty
URL adresy na akcie kontroléra:
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapControllerRoute("default", "{controller=Home}/{action=Index}"); app.Run();
Metóde MapControllerRoute()
najprv odovzdávame
názov vytváraného vzoru cesty default
a potom
samotný vzor. Vo vzore tu máme uvedené dva segmenty:
{controller=Home}
a{action=Index}
.
{}
a použitím
kľúčových slov controller
a action
hovoríme, že
pri spracovaní URL adresy sa prvý segment bude považovať za názov
kontroléra a druhý za názov akcie. Za rovnítkom uvádzame východiskovú
hodnotu, ktorá sa má použiť v prípade, že užívateľ daný segment
neuvedie. Napríklad vo chvíli, keď používateľ uvedie iba cestu
/home
, tak sa táto cesta automaticky doplní na
/home/index
a nasmeruje sa na akciu Index()
kontroléra HomeController
.
Týmto typom middleware, ktoré požiadavku smerujú na kontrolérov, sa hovorí routy.
Registrácia služieb
Pri spustení projektu by sa teda mala zavolať akcia Index()
kontroléra HomeController
. Keď ho teraz však spustíme, čaká
nás nepríjemne vyzerajúca výnimka o chýbajúcich službách:
ASP.NET Core framework sa skladá z veľkého množstva granulárnych služieb a komponentov, ktoré sú pre fungovanie MVC potrebné. Aby všetko mohlo správne fungovať tak, ako očakávame, musíme tieto služby do našej aplikácie najskôr zaregistrovať (k čomu nás nabáda aj text výnimky).
Presunieme sa preto späť do súboru Program.cs
a ešte pred
zostavením aplikácie zaregistrujeme potrebné služby pomocou metódy
AddControllersWithViews()
:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); // Tento riadok sme pridali var app = builder.Build(); app.MapControllerRoute("default", "{controller=Home}/{action=Index}"); app.Run();
Druhý pokus
Projekt spustíme a uvidíme tentoraz správny výsledok:
Port aplikácie v URL adrese budete mať pravdepodobne iný ako ja.
Na našu stránku sa dostaneme aj po uvedení celej URL adresy:
Alebo len časti:
Zopakovanie
Ešte si naposledy zopakujme ako celá aplikácia funguje.
Najskôr je požiadavka užívateľa spracovaná našimi
middlewarmi a prerútovaná (posunutá)
kontroléra HomeController
. Potom je spustená jeho akcia
Index()
. Tá sa spýta modelu na dáta a dáta uloží do kolekcie
ViewBag
. Následne je vyrenderovaný pohľad, ktorý pomocou Razor
syntaxe na určité miesta v šablóne vypisuje dáta z kolekcie
Viewbag
. Hotová stránka je odoslaná užívateľovi.
V nasledujúcom kvíze, Kvíz - MVC, pohľad, middleware, routovanie v ASP.NET Core MVC, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 264x (7.32 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#