Lekce 7 - Zpracování dat a validace v ASP.NET Core MVC
V minulé lekci, Obsluha formulářů v ASP.NET Core MVC, jsme načali zpracování formulářů a napojení modelu na pohled.
V dnešním ASP.NET Core tutoriálu dokončíme naši jednoduchou kalkulačku. Naučíme se odesílat data z formuláře zpět na server a zajistíme, aby tato data byla validní. Mimo to se taktéž zmíníme o fungování HTTP.
Budeme pokračovat s projektem z lekce Obsluha formulářů v ASP.NET Core MVC.
Odeslání formuláře
Při odeslání formuláře naší kalkulačky se zatím nic nestane. Je to z
toho důvodu, že formulář odešle data na tu samou stránku.
Požadavek tedy zachytí akce Index()
v kontroleru
HomeController
:
public IActionResult Index() { Kalkulacka kalkulacka = new Kalkulacka(); return View(kalkulacka); }
I po odeslání formuláře se tedy vytvoří nová instance kalkulačky, která má nulový výsledek a ta se nastaví pohledu. Proto je výsledek stále nula. Situaci odeslání formuláře na stránku, která ho má zpracovat, se někdy říká postback. My bychom právě na tuto situaci potřebovali reagovat jiným způsobem, než že opět vypíšeme stránku určenou pro situaci, kdy uživatel ještě nic neodeslal.
Do kontroleru HomeController
napíšeme další akci
Index()
, tentokrát s parametrem a anotovanou atributem
[HttpPost]
:
[HttpPost] public IActionResult Index(Kalkulacka kalkulacka) { if (ModelState.IsValid) { kalkulacka.VypocitejVysledek(); } return View(kalkulacka); }
V metodě nám přijde parametrem instance kalkulačky tak, jak byla
vytvořena z hodnot v odeslaném formuláři. Pokud je model
validní, což zjistíme pomocí vlastnosti
ModelState
, zavoláme metodu pro výpočet.
Nakonec vrátíme pohled, kterému předáme daný model se
zadanými hodnotami a výsledkem.
Metoda je označená atributem [HttpPost]
. Tím zjednodušeně
říkáme, že si přejeme, aby byla spuštěna pouze v případě, že
se odeslal formulář. ASP.NET vždy spouští to přetížení
akce, které se nejvíce hodí na danou situaci. Odeslání formuláře
tedy již nespadne do první akce Index()
, ale až do té
nové.
Aplikaci můžeme vyzkoušet. Již se nám bude zobrazovat výsledek operace:

Vyplněná zůstanou i ostatní pole, jelikož se hodnota
načítá z modelu, který ji má nastavenou z metody anotované atributem
[HttpPost]
.
Jak ale ASP.NET přesně pozná, že má při odesílání formuláře
vykonávat zrovna přetížení anotované atributem [HttpPost]
? A
co tento atribut ve skutečnosti znamená? Abychom dokázali na tyto otázky
odpovědět, tak si nejprve musíme aspoň zjednodušeně vysvětlit fungování
HTTP.
HTTP
Hyper Text Transfer Protocol, zkráceně HTTP, je jedním z nejrozšířenějších protokolů používaných ke komunikaci po internetu.
Komunikace pomocí tohoto protokolu je založená na dotazech (požadavcích) a odpovědích na ně. Klient posílá dotazy na webový server a ten mu nazpět zasílá odpovědi s daty. V našem případě je klientem webový prohlížeč, který žádá webový server např. o zaslání HTML stránky. Server po přijetí takového dotazu vygeneruje požadovanou stránku a odešle ji zpět v rámci odpovědi klientovi:

Dnes je již standardem zabezpečená verze tohoto protokolu, označována HTTPS.
Struktura HTTP dotazu a odpovědi
Dotazy klienta musí obsahovat především:
- typ dotazu, tedy tzv. HTTP metodu, a
- adresu dotazu nesoucí informaci o tom, jaká data a odkud jsou žádána.
Dále dotaz může (ale nemusí) ještě mít i:
- hlavičky obsahující dodatečné informace, např. o klientovi, a
- tělo s daty, která chceme poslat s dotazem na server.
Odpověď serveru se pak skládá zejména ze:
- stavu požadavku, tedy jeho úspěšnosti,
- hlaviček obsahujících dodatečné informace o přenášených datech, např. o typu dat, a
- samotných dat, kterými může být jakýkoliv textový dokument. Většinou se jedná o dokumenty ve formátu HTML, XML, JSON nebo třeba CSV.
HTTP metody
HTTP metoda dotazu označuje způsob, jakým má server na daný dotaz reagovat. Základními HTTP metodami jsou metody:
GET
(přečíst),POST
(vytvořit),PUT
(upravit),DELETE
(smazat).
Zasláním dotazu s HTTP metodou GET
např. říkáme, že po
serveru žádáme nějaká data. S touto metodou jsou tedy posílány všechny
požadavky webového prohlížeče na zaslání webové stránky. Při
potvrzení formuláře a posílání jeho hodnot se pak
nejčastěji používá metoda POST
. Data se odesílají uvnitř
HTTP dotazu na server. Ačkoli se to nemusí vždy striktně dodržovat, metoda
POST
slouží hlavně pro vkládání nových
dat.
Atributy pro HTTP metody
V ASP.NET Core MVC aplikacích se jednotlivé dotazy směrují pomocí mechanismu routování na jednotlivé akce kontroleru. V tomto mechanismu hrají roli právě i HTTP metody. U každé akce můžeme určit, jakou HTTP metodu musí dotaz mít, aby mohl danou akci vyvolat. Používáme k tomu speciální atributy metod. Pro výše uvedené HTTP metody se jedná o atributy:
[HttpGet]
– metodaGET
,[HttpPost]
– metodaPOST
,[HttpPut]
– metodaPUT
,[HttpDelete]
– metodaDELETE
.
Anotací našeho nového přetížení akce
Index()
atributem [HttpPost]
tedy říkáme, že se
má vykonat ve chvíli, kdy je zaslán dotaz na danou stránku s metodou
POST
. V našem případě se jedná o potvrzení formuláře.
Při vyžádání naší stránky prohlížečem se pošle dotaz s metodou
GET
. Pro tuto metodu však nemáme v kontroleru žádné
přetížení akce Index()
. Dotaz se proto nasměruje na naši
neanotované přetížení akce Index()
.
Ve chvíli, kdy ASP.NET nedokáže najít přetížení akce anotované vhodným atributem, tak volí přetížení bez atributu, pokud existuje.
Data v URL adrese
U metody POST
se data předávají v těle dotazu, u metody
GET
to však takto nelze. V případě použití metody
GET
můžeme využít předávání dat přímo v URL adrese.
Slouží k tomu tzv. parametry URL adresy. Jedná se o položky
typu klíč-hodnota, které píšeme na konec adresy za znak otazníku
?
a oddělujeme je znakem &
. Hodnotou takových
položek může být jakýkoliv řetězec.
Udělejme si jednoduchý příklad použití parametru předaného metodou
GET
. Kdybychom např. chtěli v URL adrese uvést věnování, pro
koho je kalkulačka vytvořena, vypadala by URL adresa takto:
Případně rozepsaná jako:
Váš port bude samozřejmě opět jiný.
Načtení parametrů v akci
Index()
Abychom takovouto hodnotu načetli, přesuneme se do první akce
Index()
, které přidáme parametr. Hodnoty
parametrů URL adresy máme v akci k dispozici skrze stejnojmenné parametry
metody:
public IActionResult Index(string jmeno) { Kalkulacka kalkulacka = new Kalkulacka(); ViewBag.Jmeno = jmeno; return View(kalkulacka); }
Parametr předáváme pohledu pomocí kolekce ViewBag
.
Pohled Index
Parametr vypíšeme v pohledu Index
v nadpisu
<h1>
:
<h1> Kalkulačka @if (ViewBag.Jmeno != null) { <text> pro @ViewBag.Jmeno</text> } </h1>
Pokud je parametr jmeno
zadaný (není null
),
vypíšeme do nadpisu ještě "pro" a obsah tohoto parametru.
Razor direktiva @if
Poprvé zde používáme speciální Razor direktivu @if
, která
funguje obdobně jako klasický if
ze C#. Jestliže uvedená
podmínka platí, vloží se do pohledu obsah následujícího bloku, v
opačném případě se vloží obsah bloku else
, pokud je
uveden.
Pokud v konstrukci @if
vypisujeme pouhý text,
měl by být obalený v elementu <text>
.
Výsledek:

Parametr bychom stejně dobře mohli místo pohledu předat modelu. V kalkulačce mě nenapadá žádné využití, v aplikaci pro generování náhodných čísel by parametr mohl udávat kolik čísel si přejeme vygenerovat.
Již tedy umíme předávat data skriptu na serveru, a to buď přes
parametry URL adresy nebo v těle HTTP dotazu
s metodou POST
. Metodu POST
používají zejména
formuláře. Parametry URL adresy využijeme pokud chceme
použít jinou HTTP metodu než POST
.
Popisky polí formuláře
Popisky u polí formuláře obsahují text s názvem
vlastnosti, ke které se váží. Názvy jako PrvniCislo
však nejsou pro uživatele příliš vábné. Proto vlastnosti ve třídě
Kalkulacka
anotujeme atributem [Display]
s
lidštějším popisem:
public class Kalkulacka { [Display(Name = "1. číslo")] public int PrvniCislo { get; set; } [Display(Name = "2. číslo")] public int DruheCislo { get; set; } public double Vysledek { get; private set; } [Display(Name = "Operace")] public string Operace { get; set; } public List<SelectListItem> MozneOperace { get; private set; } //... }
Atribut [Display]
se nachází ve jmenném prostoru
System.ComponentModel.DataAnnotations
, nezapomene si jej tedy
přidat.
Výsledek:

Validace
Posledním tématem, které si na naší kalkulačce vyzkoušíme, bude validace. Vždy je totiž nutné ověřovat, jestli data, která nám uživatel posílá, jsou v pořádku a odpovídají tomu, co očekáváme. Pokud v naší kalkulačce nezadáme číslo ve správném formátu nebo zadáme třeba text, pak by se nám nemělo podařit formulář odeslat.
Základní validace se v ASP.NET Core generují automaticky podle datového typu dané vlastnosti modelu a jsou jak na straně klienta, tak na straně serveru. Pokud zadáme neplatný vstup, zachytí ho ještě před odesláním na server validátor v JavaScriptu. Požadavek se tedy vůbec neodešle. Pro jistotu musí být vždy ta samá validace i na serveru, protože klient si může např. JavaScript vypnout.
Atributy pro validaci
Další požadavky na validaci přidáváme ve formě atributů. Pár si jich uvedeme.
Atribut [Required]
Atribut [Required]
nám umožňuje určit, že je zadání pole
nutné. Všechny nenullovatelné hodnotové typy (např. int
,
decimal
, DateTime
...) jsou považovány za
[Required]
automaticky. Pokud však chceme definovat vlastní
chybovou hlášku, která se má uživateli zobrazit při nevyplnění pole, tak
daný atribut musíme použít. Anotujme jím vlastnosti
PrvniCislo
, DruheCislo
a Operace
:
public class Kalkulacka { [Display(Name = "1. číslo")] [Required(ErrorMessage = "Zadejte prosím 1. číslo.")] public int PrvniCislo { get; set; } [Display(Name = "2. číslo")] [Required(ErrorMessage = "Zadejte prosím 2. číslo.")] public int DruheCislo { get; set; } public double Vysledek { get; private set; } [Display(Name = "Operace")] [Required(ErrorMessage = "Vyberte prosím operaci.")] public string Operace { get; set; } //... }
Chybovou hlášku definujeme nastavením vlastnosti ErrorMessage
atributu.
Atribut [Range]
U čísel můžeme dále validovat jejich rozsah pomocí atributu
[Range]
. Přidejme si jej například k vlastnostem
PrvniCislo
a DruheCislo
:
public class Kalkulacka { [Display(Name = "1. číslo")] [Required(ErrorMessage = "Zadejte prosím 1. číslo.")] [Range(1, 100, ErrorMessage = "Zadejte prosím číslo od 1 do 100.")] public int PrvniCislo { get; set; } [Display(Name = "2. číslo")] [Required(ErrorMessage = "Zadejte prosím 2. číslo.")] [Range(1, 100, ErrorMessage = "Zadejte prosím číslo od 1 do 100.")] public int DruheCislo { get; set; } //... }
Můžeme si zkusit, že se hlášky opravdu vypíší. Zkusme třeba zadat do
pole pro první číslo písmeno e
, ve druhém poli nechat nulu a
formulář potvrdit tlačítkem Vypočítej:

Vidíme, že hlášky se automaticky vypisují do elementů s atributy
asp-validation-for
, které jsou umístěné pod poli
formuláře.
Model kalkulačky je nyní plný atributů a je tedy uzpůsobený hlavně pro View, proto se těmto modelům často říká ViewModel.
Atribut [StringLength]
Atributem [StringLength]
můžeme validovat délku
řetězců:
[StringLength(5)]
Atribut
[RegularExpression]
Řetězce můžeme také validovat pomocí regulárních
výrazů, a to atributem [RegularExpression]
:
[RegularExpression("\\d+", ErrorMessage = "Neplatný kód")]
Změna chybových hlášek
U chybové hlášky informující o chybně zadaném čísle jsme si určitě
všimli, že tato hláška je v angličtině a úplně nám tedy nezapadá do
naší aplikace. Jedná se totiž o hlášku vygenerovanou validačními skripty
a skripty knihovny jQuery, které
načítáme v souboru Index.cshtml
na konci těla elementu
<body>
:
<body class="m-3"> <!-- Zbytek obsahu... --> <script src="~/lib/jquery/dist/jquery.min.js"></script> @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } </body>
Tyto hlášky naštěstí můžeme měnit rozšířením JavaScript objektu jQuery.validator.messages
,
který je vytvářen validačními skripty. Učiníme tak pomocí funkce
jQuery.extend()
.
Jelikož se jedná o použití knihovny jQuery a JavaScriptu, který není tématem tohoto kurzu, tak zbylý obsah lekce berte spíše jen jako takový bonus pro zájemce.
Přidejme si pod importované skripty nový element
<script>
a nastavme v něm vlastní chybové hlášky
informující o chybně zadaném čísle nebo číslici:
<body class="m-3"> <!-- Zbytek obsahu... --> <script src="~/lib/jquery/dist/jquery.min.js"></script> @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } <script> jQuery.extend(jQuery.validator.messages, { number: "Zadejte prosím číslo ve správném formátu.", digits: "Zadávejte prosím pouze číslice." }); </script> </body>
Definici objektu jQuery.validator.messages
a
všechny jeho nastavitelné hlášky nalezneme v souboru
jquery-validate.js
ve složce
wwwroot/lib/jquery-validation/dist/
. Hlášky však není vhodné
měnit přímo v tomto souboru, protože např. při aktualizaci knihovny s
validačními skripty by se nám změny přepsaly.
Když aplikaci nyní spustíme a vyzkoušíme si validaci, tak hlášky již budou v češtině:

To by bylo v naší kalkulačce již vše.
V následujícím kvízu, Kvíz - Formuláře, data, validace 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 755x (1.54 MB)
Aplikace je včetně zdrojových kódů v jazyce C#