IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

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...:

Pridanie pohľadu v ASP.NET Core MVC - Základy ASP.NET Core MVC - Základy ASP.NET Core MVC

V novo otvorenom okne vyberieme Razor View - Empty a potvrdíme. Pohľad sa bude volať rovnako ako metóda:

Pridanie pohľadu v ASP.NET Core MVC - Základy ASP.NET Core MVC - Základy ASP.NET Core MVC

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.
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>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,
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>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.
Majme napríklad túto adresu:
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}.
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í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:

InvalidOperationException vo Visual Studio - Základy ASP.NET Core MVC - Základy ASP.NET Core MVC

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:

Online generátor náhodných čísel
https://local­host:7258

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:

Online generátor náhodných čísel
https://local­host:7258/home/in­dex

Alebo len časti:

Online generátor náhodných čísel
https://local­host:7258/home

Zopakovanie

Ešte si naposledy zopakujme ako celá aplikácia funguje.

MVC architektúra v ASP.NET Core MVC - Základy ASP.NET Core MVC - Základy ASP.NET Core MVC

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é 260x (7.32 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Predchádzajúci článok
Prvá webová aplikácia v ASP.NET Core MVC
Všetky články v sekcii
Základy ASP.NET Core MVC
Preskočiť článok
(neodporúčame)
Kvíz - MVC, pohľad, middleware, routovanie v ASP.NET Core MVC
Článok pre vás napísal Martin Petrovaj
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor je lenivý vymýšľať nejaký slušný podpis. Venuje sa ale prevažne C#.
Aktivity