5. diel - Pohľad, middleware a routovanie v ASP.NET Core MVC
V predchádzajúcej 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šnej lekcii ASP.NET Core 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 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="en"> <head> <meta charset="utf-8" /> <title>Online random number generator</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 angličtinu,
- kódovanie
UTF-8a - titulok.
Pri weboch s viacerými podstránkami nebývajú šablóny týchto podstránok priamo výsledné HTML stránky, ale iba ich časti, ktoré sa vkladajú do tzv. layoutu. Layoutom je označovaná časť HTML kódu, ktorá je pre všetky stránky nášho webu spoločná. Typicky teda obsahuje iba hlavičku, navigáciu a pätičku webu. V šablóne podstránky sa potom nachádza iba to, čo je súčasťou danej konkrétnej podstránky. Riešenie s layoutom si ešte ukážeme ďalej v kurze.
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>Random number</h1> <p style="font-size: 2em;">@ViewBag.Number</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
- viac príkazov po sebe naraz,
tak daný kód umiestnime do bloku, ktorý začína
zavináčom @ 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>Random number</h1> <p style="font-size: 2em;"> @{ int power = ViewBag.Number * ViewBag.Number; @power } </p> </body>
V pohľadoch by sa správne nemali takéto výpočty vyskytovať. Výpočty sa umiestňujú do modelu a v 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>Random number</h1> @{ int power = ViewBag.Number * ViewBag.Number; <p style="font-size: 2em;"> @power </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
Určite 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.
Majme napríklad túto adresu:
https://www.example.com/home/index
Časť www.example.com 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 lomkou /.
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 takto:
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.Run();
Do tohto súboru budeme písať registrácie 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é cookies 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 a v 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
/controller_nam/action_name. 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}.
Obalením segmentov do zložených zátvoriek {} 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á sa 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(); // We added this line var app = builder.Build(); app.MapControllerRoute("default", "{controller=Home}/{action=Index}"); app.Run();
Druhý pokus
Projekt spustíme a uvidíme 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 používateľa spracovaná našimi
middlewarmi a preroutovaná (posunutá)
kontroléru 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á použí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é 5x (7.29 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#
