Lekce 2 - První webová aplikace v ASP.NET Core MVC

C# .NET ASP.NET ASP.NET Core Základy ASP.NET Core MVC První webová aplikace v ASP.NET Core MVC

Unicorn College ONEbit hosting Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Úvod do MVC architektury v ASP.NET Core, jsme si uvedli MVC architekturu. Dnes tyto znalosti využijeme v praxi a naprogramujeme svou první webovou aplikaci v ASP.NET Core MVC.

Kurz předpokládá základní znalosti C# .NET a HTML. Pokud něčemu nebudete rozumět, přečtěte si nejprve základní kurzy k těmto technologiím, kde je vše potřebné vysvětleno.

Tutoriály píši pro Visual Studio verzi 2017, rozhraní jiných verzí se může trochu lišit, ale určitě nijak dramaticky, takže byste vše popisované měli nalézt. Pro vývoj v ASP.NET Core 2 a vyšším ovšem potřebujete minimálně Visual Studio 2017 ve verzi 15.3.0 nebo novější, a mít nainstalovaný .NET Core 2.x SDK (případně je ke stažení na https://www.microsoft.com/…ownload/core).

Založení projektu

Naše první webová aplikace bude generátor náhodných čísel. Začněme založením nového projektu ve Visual Studio. Nový projekt založíme pomocí hlavního menu File -> New -> Project.

V dialogu vybereme jako jazyk C#, jako typ projektu ASP.NET Core Web Application a jméno zvolíme MVCNahodneCislo. Pokud zde kategorii "ASP.NET Core" nemáte, použijte odkaz "Open Visual Studio Installer" v levé části okna. ASP.NET Core naleznete v kategorii Web & Cloud, v pravé části je následně nutné zaškrtnout .NET Core development tools for Web.

Nový ASP.NET Core projekt ve Visual Studio

Jakmile dialog potvrdíme, zobrazí se další s výběrem template. Template je předgenerovaná struktura projektu. My začneme s prázdným projektem a proto vybereme prozatím Empty. Ujistěte se, že nahoře máte vybranou verzi ASP.NET Core 2.0 nebo vyšší. Potvrdíme.

Prázdný ASP.NET Core projekt ve Visual Studio

Adresářová struktura

Ačkoli jsme založili prázdný projekt, Visual Studio i tak vygenerovalo několik nových souborů. To je proto, že ASP.NET Core je framework, tedy hotové řešení, které pouze přizpůsobujeme pro náš účel.

Adresářová struktura projektu v ASP.NET Core ve Visual Studio

V Solution Exploreru po pravé straně pro začátek klikneme pravým tlačítkem na projekt a pomocí Add -> New folder vytvoříme složky Models, Views a Controllers. Právě sem přidáme komponenty naší aplikace tak, jak jsme si vysvětlovali v minulé lekci.

Přidání složek do ASP.NET Core MVC projektu

Model

Začněme modelem. Do složky Models přidáme jednoduchou třídu, kterou nazveme Generator. Bude mít následující obsah:

public class Generator
{
        private Random random = new Random();

        public int VratCislo()
        {
                return random.Next(100);
        }
}

Třída nedělá nic jiného, než že vrací náhodné číslo z privátní instance třídy Random. Prakticky nemá takovýto model valný smysl, pro nás je však důležitý princip a v budoucnu budeme úplně stejně vracet např. článek z databáze. Vytvořili jsme tedy logickou část aplikace.

Controller

Nyní přidáme Controller do složky Controllers pomocí pravého tlačítka a výběru Add -> Controller. Jako typ vybereme MVC Controller - Empty. Ostatní typy nám umožňují např. rovnou vygenerovat pohledy, použijeme je dále v kurzu.

Nový controller v ASP.NET Core MVC

Jako jméno kontroleru zvolíme HomeController. Jméno kontroleru by mělo vždy končit na Controller. HomeController je obvyklý název kontroleru, který se spustí ve chvíli, kdy na stránku přijdeme (aniž bychom zadávali další parametry, tedy jako homepage).

Home Controller v ASP.NET Core MVC

Visual Studio nám vygenerovalo novou třídu, která vypadá takto:

public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

Metoda Index() se na kontroleru zavolá ve chvíli, kdy uživatel zadá požadavek na stránku, kterou daný kontroler spravuje. Právě v této metodě vytvoříme instanci modelu, získáme si od něj data a tato data předáme pohledu.

Metoda využívá jako návratový typ rozhraní IActionResult, které reprezentuje objekt, který po dokončení požadavku zasíláme zpět prohlížeči. V našem případě mu zasíláme šablonu (objekt View). Stejně tak mu můžeme zaslat soubor, žádost o přesměrování nebo třeba data v JSON. Vrátit můžeme dokonce i jen string, který se v prohlížeči poté vypíše.

Předání dat pohledu

K předání dat máme na výběr ze 3 kolekcí, které jsou přístupné jak v kontroleru, tak později v pohledu. V kontroleru kolekci naplníme daty z modelu a v pohledu z ní data vypíšeme do připravené HTML šablony.

Můžeme použít kolekce:

  • ViewData - Kolekce na způsob Dictionary, kam vkládáme jednotlivé proměnné pro šablonu pod textové klíče. Používala se hlavně předtím, než C# zavedl klíčové slovo dynamic.
  • ViewBag - ViewBag využívá dynamické vlastnosti, které jsou v C# .NET od verze 4.0. Místo klíčů zapisujeme rovnou do vlastností, které se na ViewBag vytvoří.
  • TempData - Poměrně matoucí kolekce, sloužící k předání dat zejména při přesměrování. Data jsou smazána po dokončení požadavku.

Je vlastně jedno, jestli budeme data do šablony předávat pomocí ViewBag nebo ViewData, jelikož ViewBag interně využívá pro své vlastnosti právě ViewData. To znamená, že cokoliv uložíte do ViewBagu, to bude přístupné i jako položka ViewData a naopak. Výhodou ViewBagu je ovšem to, že pro získání složitějšího typu nemusíme provádět konverzi (type casting). Microsoft ve své dokumentaci ale využívá spíš starší ViewData, zčásti je to proto, že ViewBag momentálně není dostupný v Razor Pages (jiný typ stránek, který se dá v Core vytvářet). Na výběru kolekce příliš nezáleží.

Někdy (u architektury MVVM - Model-View-ViewModel) se můžete setkat i s posíláním dat pohledu přes k tomu určený objekt naplněný daty, tzv. ViewModel, tento způsob si ale ukážeme až dále v kurzu.

Upravme metodu Index() v kontroleru tak, aby metoda před vrácením pohledu získala data z modelu a ta uložila do ViewBag:

public IActionResult Index()
{
        Generator generator = new Generator();
        ViewBag.Cislo = generator.VratCislo();
        return View();
}

Abychom mohli přistoupit k modelu, je třeba přidat using. I když to všichni jistě umíte, pro jistotu zopakuji, že kliknete na červeně podtržený název třídy Generator a poté na žárovku vlevo, kde nakliknete přidání daného usingu. Pokud by vám to nefungovalo, můžete using přidat i manuálně jako using MVCNahodneCislo.Models na úplný začátek souboru. V kontroleru jsme hotoví. Zareagovali jsme na požadavek na indexovou stránku a propojili model a pohledem.

View

V naší aplikaci nám nyní chybí šablona (pohled), ve které výstup zobrazíme uživateli. Pojmy šablona a pohled budu v kurzu zaměňovat a myslím tím vždy pohled. View nejjednodušeji přidáme přímo z příslušného kontroleru. Klikneme pravým kamkoli do metody Index() a zvolíme Add View.

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

Pohled se bude jmenovat stejně jako metoda. Potvrdíme.

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

Je nám vygenerována HTML šablona s následujícím obsahem:

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

Na začátku vidíme zavináč a C# kód. 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ě.

Určitě jste podle obsahu vygenerované šablony přišli na to, že šablona není přímo výsledná HTML stránka, ale pouze její část, která se poté vloží do layoutu. Ten ovšem zatím nemáme definovaný, výstup tedy nebude HTML validní, což u prvního příkladu zanedbáme. V této šabloně se bude nacházet pouze to, co je součástí jedné konkrétní podstránky našeho webu. Šabloně nastavíme její titulek a vložíme do ní číslo z modelu pomocí ViewBag a Razor @ direktivy. Její kód bude nyní následující:

@{
    ViewBag.Title = "Online generátor náhodných čísel";
}

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

Původní nastavení titulku přes ViewData jsem nahradil ViewBag, aby to bylo stejné, ale tato změna není nutná. Číslo vypíšeme z ViewBag, kam ho uložil kontroler. Ten ho získal z modelu, který ho vygeneroval.

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

Kdybychom naší aplikaci nyní spustili (Ctrl + F5), zobrazila by se pouze "Hello World" hláška a náš kontroler by se nespustil vůbec. Jelikož jsme na začátku pro názornost zvolili prázdnou šablonu, musíme HomeController nejdříve naroutovat, aby se spustil jako výchozí. Právě tomuto mechanismu napojování URL adres na kontrolery nebo jiné části aplikace se říká routování a my ho tentokrát provedeme v souboru Startup.cs. Obsah souboru vypadá asi následovně:

// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.Run(async (context) =>
    {
        await context.Response.WriteAsync("Hello World!");
    });
}

Do této metody budeme vkládat tzv. middleware. Ty si v ASP.NET Core můžeme představit jako sérii filtrů, přes které postupně putuje požadavek od uživatele, než se najde ten vhodný, který jej zpracuje. Mají podobu extension metod na rozhraní IApplicationBuilder (některým z vás pravděpodobně připomenou návrhový vzor Chain of responsibility).

Každý middleware v řetězci má pouze omezenou a specifickou roli ve zpracování požadavku - první může např. plnit jen funkci loggeru, další middleware bude hledat nějakou cookie nebo autorizační token a jestli ho nenajde, 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ě.

Abychom se hned po spuštění aplikace uživatel nasměroval na HomeController, můžeme použít middleware app.UseMvcWithDefaultRoute(), který vložíme doprostřed metody Configure().

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

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseMvcWithDefaultRoute(); // Tento řádek jsme přidali

    app.Run(async (context) =>
    {
        await context.Response.WriteAsync("Hello World!");
    });
}

Při spuštění aplikace se nyní tedy spustí HomeController a zavolá se jeho veřejná metoda Index(). Ekvivalentem k defaultnímu routování pomocí UseMvcWithDefaultRoute() by mohl být následující callback, který by kontroler a jeho metodu explicitně nastavoval:

app.UseMvc(routeBuilder => routeBuilder.MapRoute(name: "Default",
        template: "{controller}/{action}/{id?}",
        defaults: new { controller = "Home", action = "Index" }
));

My však zůstaňme u předchozí varianty, k routování se blíže vrátíme později. Když ovšem nyní projekt spustíme, čeká nás nepříjemně vypadající error (nebo výjimka přímo ve Visual Studiu):

Chyba v aplikaci – InvalidOperationException: Unable to find the required services

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 přidat (k čemuž nás nabádá i text výjimky).

Přesuneme se proto do metody ConfigureServices() a zavoláním metody AddMvc() přidáme do kolekce služeb pro naši aplikaci vše potřebné pro fungování MVC:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
}

Projekt spustíme. Uvidíte následující, tentokrát správný výsledek:

Webová aplikace v ASP.NET Core MVC – Náhodné číslo

Port budete mít jiný než já na screenshotu.

Zopakování

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

MVC architektura v ASP.NET Core MVC

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

Zdrojové kódy dnešního projektu jsou ke stažení níže, bude tomu tak ve všech lekcích. Pokud se vám něco nepovedlo, můžete si tedy najít chybu. V příští lekci, Obsluha formulářů v ASP.NET Core MVC, se podíváme na obsluhu formulářů.


 

Stáhnout

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

 

 

Článek pro vás napsal Martin Petrovaj
Avatar
Jak se ti líbí článek?
1 hlasů
Autor je lenivý vymýšľať nejaký slušný podpis. Venuje sa ale prevažne C#.
Miniatura
Všechny články v sekci
Základy ASP.NET Core MVC
Miniatura
Následující článek
Obsluha formulářů v ASP.NET Core MVC
Aktivity (6)

 

 

Komentáře

Avatar
vdavidv
Člen
Avatar
vdavidv:10. září 3:23

jen dotaz, přídání pohledu umožnuje i free verze visual studia community? Nemůžu se k takové nabídce nikde proklikat.

 
Odpovědět 10. září 3:23
Avatar
vdavidv
Člen
Avatar
Odpovídá na vdavidv
vdavidv:10. září 3:28

už vyřešeno

 
Odpovědět 10. září 3:28
Avatar
Odpovídá na vdavidv
Michal Haňáček:10. září 7:34

Mohl by jsi se podělit o to řešení? Někomu by to mohlo být nápomocné, nemyslíš?

Odpovědět 10. září 7:34
Každé rozhodnutí a každý krok v životě nás někam posune. Bohužel jen některé nás posouvají dopředu.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 3 zpráv z 3.