7. diel - Spracovanie dát a validácia v ASP.NET Core MVC
V minulej lekcii, Obsluha formulárov v ASP.NET Core MVC , sme načali spracovanie formulárov a napojenie modelu na pohľad.
V dnešnom ASP.NET Core tutoriále dokončíme našu jednoduchú kalkulačku. Naučíme sa odosielať dáta z formulára späť na server a zaistíme, aby tieto dáta boli validné. Okrem toho sa taktiež zmienime o fungovaní HTTP.
Budeme pokračovať s projektom z lekcie Obsluha formulárov v ASP.NET Core MVC.
Odoslanie formulára
Pri odoslaní formulára našej kalkulačky sa zatiaľ nič nestane. Je to z
toho dôvodu, že formulár odošle dáta na tú istú
stránku. Požiadavka teda zachytí akcie Index()
v
kontroléri HomeController
:
public IActionResult Index() { Kalkulacka kalkulacka = new Kalkulacka(); return View(kalkulacka); }
Aj po odoslaní formulára sa teda vytvorí nová inštancia kalkulačky, ktorá má nulový výsledok a tá sa nastaví pohľadu. Preto je výsledok stále nula. Situáciu odoslania formulára na stránku, ktorá ho má spracovať, sa niekedy hovorí postback. My by sme práve na túto situáciu potrebovali reagovať iným spôsobom, než že opäť vypíšeme stránku určenú pre situáciu, keď používateľ ešte nič neodoslal.
Do kontroléra HomeController
napíšeme ďalšiu akciu
Index()
, tentoraz s parametrom a anotovanou atribútom
[HttpPost]
:
[HttpPost] public IActionResult Index(Kalkulacka kalkulacka) { if (ModelState.IsValid) { kalkulacka.VypocitejVysledek(); } return View(kalkulacka); }
V metóde nám príde parametrom inštancie kalkulačky tak, ako bola
vytvorená z hodnôt v odoslanom formulári. Ak je model
validný, čo zistíme pomocou vlastnosti
ModelState
, zavoláme metódu na výpočet.
Nakoniec vrátime pohľad, ktorému odovzdáme daný model so
zadanými hodnotami a výsledkom.
Metóda je označená atribútom [HttpPost]
. Tým zjednodušene
hovoríme, že si prajeme, aby bola spustená iba v prípade, že sa
odoslal formulár. ASP.NET vždy spúšťa to preťaženie
akcie, ktoré sa najviac hodí na danú situáciu. Odoslanie formulára
teda už nespadne do prvej akcie Index()
, ale až do tej novej.
Aplikáciu môžeme vyskúšať. Už sa nám bude zobrazovať výsledok operácie:
Vyplnené zostanú aj ostatné polia, pretože sa hodnota
načíta z modelu, ktorý ju má nastavenú z metódy anotovanej atribútom
[HttpPost]
.
Ako ale ASP.NET presne pozná, že má pri odosielaní formulára vykonávať
práve preťaženie anotované atribútom [HttpPost]
? A čo tento
atribút v skutočnosti znamená? Aby sme dokázali na tieto otázky odpovedať,
tak si najskôr musíme aspoň zjednodušene vysvetliť fungovanie HTTP.
HTTP
Hyper Text Transfer Protocol, skrátene HTTP, je jedným z najrozšírenejších protokolov používaných na komunikáciu po internete.
Komunikácia pomocou tohto protokolu je založená na otázkach (požiadavkách) a odpovediach na ne. Klient posiela otázky na webový server a ten mu naspäť zasiela odpovede s dátami. V našom prípade je klientom webový prehliadač, ktorý žiada webový server napr. o zaslanie HTML stránky. Server po prijatí takejto otázky vygeneruje požadovanú stránku a odošle ju späť v rámci odpovede klientovi:
Dnes je už štandardom zabezpečená verzia tohto protokolu, označovaná HTTPS.
Štruktúra HTTP otázky a odpovede
Otázky klienta musia obsahovať predovšetkým:
- typ dotazu, teda tzv. HTTP metódu, a
- adresu dotazu nesúcu informáciu o tom, aké dáta a odkiaľ sú žiadané.
- hlavičky obsahujúce dodatočné informácie, napr. o klientovi, a
- telo s dátami, ktoré chceme poslať s otázkou na server.
- stavu požiadavky, teda jeho úspešnosti,
- hlavičiek obsahujúcich dodatočné informácie o prenášaných dátach, napr. o type dát, a
- samotných dát, ktorými môže byť akýkoľvek textový dokument. Väčšinou sa jedná o dokumenty vo formáte HTML, XML, JSON alebo napríklad CSV.
HTTP metóda dotazu označuje spôsob, akým má server na danú otázku reagovať. Základnými HTTP metódami sú metódy:
GET
(prečítať),POST
(vytvoriť),PUT
(upraviť),DELETE
(zmazať).
GET
napr. hovoríme, že po
serveri žiadame nejaké dáta. S touto metódou sú teda posielané všetky
požiadavky webového prehliadača na zaslanie webovej stránky. Pri
potvrdení formulára a posielaní jeho hodnôt sa potom
najčastejšie používa metóda POST
. Dáta sa odosielajú vo
vnútri HTTP dotazu na server. Hoci sa to nemusí vždy striktne dodržiavať,
metóda POST
slúži hlavne na vkladanie nových
dát.
Atribúty pre HTTP metódy
V ASP.NET Core MVC aplikáciách sa jednotlivé otázky smerujú pomocou mechanizmu routovania na jednotlivé akcie kontroléra. V tomto mechanizme hrajú rolu práve aj HTTP metódy. Pri každej akcii môžeme určiť, akú HTTP metódu musí dotaz mať, aby mohol danú akciu vyvolať. Používame na to špeciálne atribúty metód. Pre vyššie uvedené HTTP metódy sa jedná o atribúty:
[HttpGet]
- metódaGET
,[HttpPost]
- metódaPOST
,[HttpPut]
- metódaPUT
,[HttpDelete]
- metódaDELETE
.
Index()
atribútom [HttpPost]
teda hovoríme, že sa
má vykonať vo chvíli, keď je zaslaná otázka na danú stránku s metódou
POST
. V našom prípade sa jedná o potvrdenie formulára.
Pri vyžiadaní našej stránky prehliadačom sa pošle dotaz s metódou
GET
. Pre túto metódu však nemáme v kontroléri žiadne
preťaženie akcie Index()
. Otázka sa preto nasmeruje na našu
neanotované preťaženie akcie Index()
.
Vo chvíli, keď ASP.NET nedokáže nájsť preťaženie akcie anotovanej vhodným atribútom, tak volí preťaženie bez atribútu, pokiaľ existuje.
Dáta v URL adrese
Pri metóde POST
sa dáta odovzdávajú v tele dotazu, pri
metóde GET
to však takto nemožno. V prípade použitia metódy
GET
môžeme využiť odovzdávanie dát priamo v URL adrese.
Slúžia na to tzv. parametre URL adresy. Ide o položky typu
kľúč-hodnota, ktoré píšeme na koniec adresy za znak otáznika
?
a oddeľujeme ich znakom &
. Hodnotou takýchto
položiek môže byť akýkoľvek reťazec.
Urobme si jednoduchý príklad použitia parametra odovzdaného metódou
GET
. Keby sme napr. chceli v URL adrese uviesť venovanie, pre koho
je kalkulačka vytvorená, vyzerala by URL adresa takto:
Prípadne rozpísaná ako:
Váš port bude samozrejme opäť iný.
Načítanie parametrov v akcii
Index()
Aby sme takúto hodnotu načítali, presunieme sa do prvej akcie
Index()
, ktoré pridáme parameter. Hodnoty
parametrov URL adresy máme v akcii k dispozícii cez rovnomenné parametre
metódy:
public IActionResult Index(string jmeno) { Kalkulacka kalkulacka = new Kalkulacka(); ViewBag.Jmeno = jmeno; return View(kalkulacka); }
Parameter odovzdávame pohľadu pomocou kolekcie ViewBag
.
Pohľad Index
Parameter vypíšeme v pohľade Index
v nadpise
<h1>
:
<h1> Kalkulačka @if (ViewBag.Jmeno != null) { <text> pro @ViewBag.Jmeno</text> } </h1>
Pokiaľ je parameter jmeno
zadaný (nie je null
),
vypíšeme do nadpisu ešte "pre" a obsah tohto parametra.
Razor direktíva @if
Prvýkrát tu používame špeciálny Razor direktívu @if
,
ktorá funguje obdobne ako klasický if
zo C#. Ak uvedená
podmienka platí, vloží sa do pohľadu obsah nasledujúceho bloku, v opačnom
prípade sa vloží obsah bloku else
, pokiaľ je uvedený.
Pokiaľ v konštrukcii @if
vypisujeme obyčajný
text, mal by byť obalený v elemente <text>
.
Výsledok:
Parameter by sme rovnako dobre mohli namiesto pohľadu odovzdať modelu. V kalkulačke ma nenapadá žiadne využitie, v aplikácii na generovanie náhodných čísel by parameter mohol udávať koľko čísel si prajeme vygenerovať.
Už teda vieme odovzdávať dáta skriptu na serveri, a to buď cez
parametre URL adresy alebo v tele HTTP dotazu
s metódou POST
. Metódu POST
používajú najmä
formuláre. Parametre URL adresy využijeme ak chceme použiť
inú HTTP metódu ako POST
.
Popisky polí formulára
Popisy pri poliach formulára obsahujú text s názvom
vlastnosti, ku ktorej sa viažu. Názvy ako PrvniCislo
však nie sú pre používateľov príliš vábne. Preto vlastnosti v triede
Kalkulacka
anotujeme atribútom [Display]
s
ľudskejším popisom:
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 = "Operácia")] public string Operace { get; set; } public List<SelectListItem> MozneOperace { get; private set; } //... }
Atribút [Display]
sa nachádza v mennom priestore
System.ComponentModel.DataAnnotations
, nezabudne si ho teda
pridať.
Výsledok:
Validácia
Poslednou témou, ktorú si na našej kalkulačke vyskúšame, bude validácia. Vždy je totiž nutné overovať, či dáta, ktoré nám užívateľ posiela, sú v poriadku a zodpovedajú tomu, čo očakávame. Pokiaľ v našej kalkulačke nezadáme číslo v správnom formáte alebo zadáme napríklad text, potom by sa nám nemalo podariť formulár odoslať.
Základné validácie sa v ASP.NET Core generujú automaticky podľa dátového typu danej vlastnosti modelu a sú tak na strane klienta, ako aj na strane servera. Pokiaľ zadáme neplatný vstup, zachytí ho ešte pred odoslaním na server validátor v JavaScripte. Požiadavka sa teda vôbec neodošle. Pre istotu musí byť vždy tá istá validácia aj na serveri, pretože klient si môže napr. JavaScript vypnúť.
Atribúty pre validáciu
Ďalšie požiadavky na validáciu pridávame vo forme atribútov. Pár si ich uvedieme.
Atribút [Required]
Atribút [Required]
nám umožňuje určiť, že je zadanie
poľa nutné. Všetky nenullovateľné hodnotové typy (napr. int
,
decimal
, DateTime
...) sú považované za
[Required]
automaticky. Pokiaľ však chceme definovať vlastnú
chybovú hlášku, ktorá sa má užívateľovi zobraziť pri nevyplnení poľa,
tak daný atribút musíme použiť. Anotujme ním vlastnosti
PrvniCislo
, DruheCislo
a Operace
:
public class Kalkulacka { [Display(Name = "1. číslo")] [Required(ErrorMessage = "Zadajte prosím 1. číslo.")] public int PrvniCislo { get; set; } [Display(Name = "2. číslo")] [Required(ErrorMessage = "Zadajte prosím 2. číslo.")] public int DruheCislo { get; set; } public double Vysledek { get; private set; } [Display(Name = "Operácia")] [Required(ErrorMessage = "Vyberte prosím operáciu.")] public string Operace { get; set; } //... }
Chybovú hlášku definujeme nastavením vlastnosti ErrorMessage
atribútu.
Atribút [Range]
Pri číslach môžeme ďalej validovať ich rozsah pomocou atribútu
[Range]
. Pridajme si ho napríklad k vlastnostiam
PrvniCislo
a DruheCislo
:
public class Kalkulacka { [Display(Name = "1. číslo")] [Required(ErrorMessage = "Zadajte prosím 1. číslo.")] [Range(1, 100, ErrorMessage = "Zadajte prosím číslo od 1 do 100.")] public int PrvniCislo { get; set; } [Display(Name = "2. číslo")] [Required(ErrorMessage = "Zadajte prosím 2. číslo.")] [Range(1, 100, ErrorMessage = "Zadajte prosím číslo od 1 do 100.")] public int DruheCislo { get; set; } //... }
Môžeme si skúsiť, že sa hlášky skutočne vypíšu. Skúsme treba
zadať do poľa pre prvé číslo písmeno e
, v druhom poli nechať
nulu a formulár potvrdiť tlačidlom Vypočítaj:
Vidíme, že hlášky sa automaticky vypisujú do elementov s atribútmi
asp-validation-for
, ktoré sú umiestnené pod poľami
formulára.
Model kalkulačky je teraz plný atribútov a je teda prispôsobený hlavne pre View, preto sa týmto modelom často hovorí ViewModel.
Atribút [StringLength]
Atribútom [StringLength]
môžeme validovať dĺžku
reťazcov:
[StringLength(5)]
Atribút
[RegularExpression]
Reťazce môžeme tiež validovať pomocou regulárnych
výrazov, a to atribútom [RegularExpression]
:
[RegularExpression("\\d+", ErrorMessage = "Neplatný kód")]
Zmena chybových hlášok
U chybovej hlášky informujúcej o chybne zadanom čísle sme si určite
všimli, že táto hláška je v angličtine a úplne nám teda nezapadá do
našej aplikácie. Ide totiž o hlášku vygenerovanú validačnými skriptmi a
skriptmi knižnice jQuery, ktoré
načítavame v súbore Index.cshtml
na konci tela elementu
<body>
:
<body class="m-3"> <!-- Zbytek obsahu... --> <script src="~/lib/jquery/dist/jquery.min.js"></script> @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } </body>
Tieto hlášky našťastie môžeme meniť rozšírením JavaScript objektu jQuery.validator.messages
,
ktorý je vytváraný validačnými skriptami. Urobíme tak pomocou funkcie
jQuery.extend()
.
Keďže sa jedná o použitie knižnice jQuery a JavaScriptu, ktorý nie je témou tohto kurzu, tak zvyšný obsah lekcie berte skôr len ako taký bonus pre záujemcov.
Pridajme si pod importované skripty nový element
<script>
a nastavme v ňom vlastné chybové hlášky
informujúce o chybne zadanom čísle alebo čí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>
Definíciu objektu jQuery.validator.messages
a
všetky jeho nastaviteľné hlášky nájdeme v súbore
jquery-validate.js
v priečinku
wwwroot/lib/jquery-validation/dist/
. Hlášky však nie je vhodné
meniť priamo v tomto súbore, pretože napr. pri aktualizácii knižnice s
validačnými skriptmi by sa nám zmeny prepísali.
Keď aplikáciu teraz spustíme a vyskúšame si validáciu, tak hlášky už budú v slovenčine:
To by bolo v našej kalkulačke už všetko.
V nasledujúcom kvíze, Kvíz - Formuláre, dáta, validácia 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é 723x (1.54 MB)
Aplikácia je vrátane zdrojových kódov v jazyku C#