IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 5 - Pohled, middleware a routování v ASP.NET Core MVC

V minulé lekci, První webová aplikace v ASP.NET Core MVC, jsme začali s tvorbou naší první webové aplikace v ASP.NET Core MVC, kterou je generátor náhodných čísel.

V dnešním ASP.NET Core tutoriálu si do naší první webové aplikace v ASP.NET Core MVC doplníme pohled, middleware a routování.

View

V naší aplikaci nám ještě chybí šablona (pohled), ve které výstup zobrazíme uživateli.

Pojmy šablona a pohled se budou v kurzu zaměňovat, bude tím myšlen vždy pohled.

View (pohled) nejjednodušeji přidáme přímo z příslušného kontroleru. Klikneme pravým tlačítkem kamkoli do metody Index() a zvolíme Add View...:

Přidání pohledu v ASP.NET Core MVC - Základy ASP.NET Core MVC

V nově otevřeném okně vybereme Razor View - Empty a potvrdíme. Pohled se bude jmenovat stejně jako metoda:

Přidání pohledu v ASP.NET Core MVC - Základy ASP.NET Core MVC

Po potvrzení vytvoření se nám vygeneruje HTML šablona s následujícím obsahem:

@*
    For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}

Na začátku vidíme komentář zapsaný mezi zavináče s hvězdičkami a blok pro C# kód začínající zavináčem a ohraničený složenými závorkami. To je syntaxe tzv. Razor engine, který slouží pro vkládání C# kódu do HTML. Existuje ještě několik dalších renderovacích enginů, ale téměř se nepoužívají.

Již víme, že všechna logika by měla být obsažena v modelech. V pohledech budeme C# používat pouze k výpisu hotových dat, které jsme z modelů získali. Razor direktiv by v šablonách mělo být co možná nejméně.

Základní struktura

Aktuální obsah šablony smažeme a vytvoříme si validní strukturu 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>

Jak můžeme vidět, zatím se jedná o klasické HTML. Pokud jsme tedy absolvovali základní kurz tvorby webových stránek, tak by nás zde nemělo nic překvapit. Stránce jsme nastavili:

  • jazyk na češtinu,
  • kódování UTF-8 a
  • titulek.

U webů s více podstránkami nebývají šablony těchto podstránek přímo výsledné HTML stránky, ale pouze jejich části, které se vkládají do tzv. layoutu. Layoutem je označována část HTML kódu, která je pro všechny stránky našeho webu společná. Typicky tedy obsahuje pouze hlavičku, navigaci a patičku webu. V šabloně podstránky se pak nachází pouze to, co je součástí dané konkrétní podstránky. Řešení s layoutem si ještě ukážeme dále v kurzu.

Tělo stránky

Nyní již do šablony doplníme samotný obsah v těle <body>. Stránka bude zobrazovat pouze jeden nadpis a odstavec s vygenerovaným náhodným číslem:

<body>
    <h1>Náhodné číslo</h1>
    <p style="font-size: 2em;">@ViewBag.Cislo</p>
</body>

Náhodné číslo vypisujeme z kolekce ViewBag, kam ho uložil kontroler. Ten ho získal z modelu, který ho vygeneroval.

Základní Razor syntaxe

Ke kolekci ViewBag přistupujeme přes Razor direktivu @. Pokaždé, když chceme v šabloně vykonat C# příkaz, který má do šablony vložit nějaký obsah, tak před něj napíšeme zavináč @.

V případě, kdy potřebujeme vykonat:

  • příkaz, který nic nevrací,
  • příkaz přiřazení nebo
  • po sobě více příkazů najednou,

tak daný kód umístíme do bloku, který začíná zavináčem @ a je ohraničený složenými závorkami {}. Takto bychom například mohli vypsat druhou mocninu vygenerovaného čísla s uložením výsledku do proměnné:

<body>
    <h1>Náhodné číslo</h1>
    <p style="font-size: 2em;">
        @{
            int mocnina = ViewBag.Cislo * ViewBag.Cislo;
            @mocnina
        }
    </p>
</body>

V pohledech by se správně neměly takové výpočty vyskytovat. Výpočty se umisťují do v modelu a v pohledu přes kontroler se pouze předávají výsledky. Docílí se tak lepší přehlednosti našeho kódu, když bude většina logiky umístěna pouze v modelu.

Z bloku kódu můžeme vracet i HTML elementy. Následující ukázka vygeneruje stejný HTML kód jako ta předchozí:

<body>
    <h1>Náhodné číslo</h1>
    @{
        int mocnina = ViewBag.Cislo * ViewBag.Cislo;

        <p style="font-size: 2em;">
            @mocnina
        </p>
    }
</body>

Tyto dvě ukázky berme opravdu jen jako ukázky. V naší aplikaci budeme pracovat s verzí vypisující pouze vygenerované náhodné číslo, ne jeho druhou mocninu.

URL adresa

Jistě víte, že každá webová stránka je na internetu identifikována svou unikátní URL adresou. Taková URL adresa se skládá především z:

  • doménového jména a
  • cesty.

Mějme například tuto adresu:

https://www.domena.cz/home/index

Část www.domena.cz je zde doménovým jménem a část /home/index je pak cestou. Doménové jméno bývá pro jeden web většinou neměnné. Cesta už se však pro každou stránku webu liší. Právě cesta URL adresy totiž identifikuje konkrétní stránku daného webu. Cesta se skládá z libovolného množství segmentů oddělených lomítkem /.

Výše zvolená adresa nebyla zvolena náhodně. Když se podíváme na její cestu /home/index, tak ta odpovídá struktuře naší aplikace. V naší aplikaci máme kontroler HomeController, který má akci Index(). Uvedená cesta splňuje obecně používanou konvenci řešící směrování (mapování) cesty URL adresy na akce kontrolerů v ASP.NET aplikacích. Prvním segmentem je vždy název kontroleru, druhým je název akce daného kontroleru a zbylé segmenty pak slouží jako případné parametry.

Middleware, zpracování požadavků a routování

Kdybychom naši aplikaci nyní spustili (např. klávesovou zkratkou Ctrl + F5), zobrazila by se pouze hláška "Hello World!" a náš kontroler by se nespustil vůbec. Jelikož jsme při vytváření projektu zvolili prázdnou šablonu, musíme HomeController sami nasměrovat, aby se spustil jako výchozí.

Právě tomuto mechanismu směrování URL adres na kontrolery nebo jiné části aplikace se říká routování.

Routování se nastavuje v souboru Program.cs, jehož obsah nyní vypadá asi následovně:

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

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

app.Run();

Do tohoto souboru budeme psát registrace služeb a většinu konfigurací aplikace, jejíž sestavení zajišťuje instance třídy WebApplicationBuilder s metodou Build(). Jak si můžeme všimnout, hláška "Hello World!" by se po spuštění aplikace zobrazila proto, že je zde ve výchozím stavu pomocí metody MapGet() nastaveno směrování cesty / na navrácení právě tohoto řetězce.

Do souboru Program.cs můžeme do sestavené aplikace dále psát tzv. middleware. Middleware si v ASP.NET Core můžeme představit jako sérii filtrů, přes které postupně putuje požadavek od uživatele na server, než se najde ten vhodný, který jej zpracuje. Mají podobu rozšiřujících metod na instanci sestavené aplikace (některým z vás pravděpodobně připomenou návrhový vzor Chain of responsibility, protože se řetězí).

Každý middleware v řetězci má pouze omezenou a specifickou roli ve zpracování požadavku - např. první může plnit jen funkci loggeru, další middleware bude hledat nějakou cookie nebo autorizační token. A pokud nenajde co hledá, vrátí chybovou hlášku nebo uživatele přesměruje. Např. middleware UseFileServer() nám umožní jako odpověď vrátit statický obsah (skripty v Javascriptu, obrázky, CSS soubory atd.) našeho projektu a podobně.

V .NET 5.0 a starších verzích je kód souboru Program.cs vyčleněn do metod ConfigureServices() a Configure() v souboru Startup.cs. V metodě ConfigureServices() se registrují služby a v metodě Configure() se konfiguruje middleware na již sestavené aplikaci.

Routování na kontroler

Budeme tedy chtít, aby se uživatel hned po spuštění aplikace nasměroval na kontroler HomeController a jeho akci Index(). Zároveň budeme chtít, aby všechny cesty splňovaly výše uvedenou konvenci, tedy aby měly vzor /nazev_kontroleru/nazev_akce. K tomu využijeme middleware MapControllerRoute(), který se stará o napojení cesty URL adresy na akce kontroleru:

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapControllerRoute("default", "{controller=Home}/{action=Index}");

app.Run();

Metodě MapControllerRoute() nejprve předáváme název vytvářeného vzoru cesty default a poté samotný vzor. Ve vzoru zde máme uvedené dva segmenty:

  • {controller=Home} a
  • {action=Index}.

Obalením segmentů do složených závorek {} a použitím klíčových slov controller a action říkáme, že při zpracování URL adresy se první segment bude považovat za název kontroleru a druhý za název akce. Za rovnítkem uvádíme výchozí hodnotu, která se má použít v případě, že uživatel daný segment neuvede. Například ve chvíli, kdy uživatel uvede pouze cestu /home, tak se tato cesta automaticky doplní na /home/index a nasměruje se na akci Index() kontroleru HomeController.

Těmto typům middleware, které požadavek směrují na kontrolery, se říká routy.

Registrace služeb

Při spuštění projektu by se tedy měla zavolat akce Index() kontroleru HomeController. Když jej nyní ovšem spustíme, čeká nás nepříjemně vypadající výjimka o chybějících službách:

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

ASP.NET Core framework se skládá z velkého množství granulárních služeb a komponent, které jsou pro fungování MVC potřebné. Aby vše mohlo správně fungovat tak, jak očekáváme, musíme tyto služby do naší aplikace nejdříve zaregistrovat (k čemuž nás nabádá i text výjimky).

Přesuneme se proto zpět do souboru Program.cs a ještě před sestavením aplikace zaregistrujeme potřebné služby pomocí metody AddControllersWithViews():

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews(); //  Tento řádek jsme přidali 

var app = builder.Build();

app.MapControllerRoute("default", "{controller=Home}/{action=Index}");

app.Run();

Druhý pokus

Projekt spustíme a uvidíme tentokrát správný výsledek:

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

Port aplikace v URL adrese budete mít pravděpodobně jiný než já.

Na naši stránku se dostaneme i po uvedení celé URL adresy:

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

Nebo jen části:

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

Zopakování

Ještě si naposledy zopakujme jak celá aplikace funguje.

MVC architektura v ASP.NET Core MVC - Základy ASP.NET Core MVC

Nejdříve je požadavek uživatele zpracován našimi middlewary a přeroutován (posunut) kontroleru HomeController. Poté je spuštěna jeho akce Index(). Ta se zeptá modelu na data a data uloží do kolekce ViewBag. Následně je vyrenderován pohled, který pomocí Razor syntaxe na určitá místa v šabloně vypisuje data z kolekce Viewbag. Hotová stránka je odeslána uživateli.

V následujícím kvízu, Kvíz - MVC, pohled, middleware, routování v ASP.NET Core MVC, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 231x (5.6 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

Předchozí článek
První webová aplikace v ASP.NET Core MVC
Všechny články v sekci
Základy ASP.NET Core MVC
Přeskočit článek
(nedoporučujeme)
Kvíz - MVC, pohled, middleware, routování v ASP.NET Core MVC
Článek pro vás napsal Martin Petrovaj
Avatar
Uživatelské hodnocení:
275 hlasů
Autor je lenivý vymýšľať nejaký slušný podpis. Venuje sa ale prevažne C#.
Aktivity