Black Friday Black Friday
Black Friday výprodej! Až 80 % extra bodů zdarma! Více informací zde

Lekce 4 - Zpracování dat a validace v ASP.NET Core MVC

C# .NET ASP.NET ASP.NET Core Základy ASP.NET Core MVC Zpracování dat a validace 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, Obsluha formulářů v ASP.NET Core MVC, jsme načali zpracování formulářů a napojení modelu na pohled. Jednoduchou kalkulačku dnes v C# .NET tutoriálu dokončíme.

Odeslání formuláře

Při odeslání našeho formuláře 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í metoda Index() v kontroleru, která vypadá následovně:

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 přidáme další metodu Index(), tentokrát s parametrem a atributem HttpPost:

[HttpPost]
public IActionResult Index(Kalkulacka kalkulacka)
{
        if (ModelState.IsValid)
        {
                kalkulacka.Vypocitej();
        }

        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í třídy 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 ří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í metody, které se nejvíce hodí na danou situaci. Odeslání formuláře tedy již nespadne do první metody Index(), ale až do té nové.

Aplikaci můžeme vyzkoušet, již se nám bude zobrazovat výsledek operace:

Kalkulačka v ASP.NET MVC

Vyplněná zůstanou i ostatní pole, jelikož se hodnota načítá z modelu, který ji má nastavenou z POST.

GET a POST

Slušelo by se říci, že kromě metody POST existuje ještě metoda GET. Obě metody můžeme použít k zaslání dat naší aplikaci.

Již víme, že metodou POST se odesílají hodnoty z formuláře. Data se odešlou uvnitř HTTP požadavku na server. Ačkoli se to nemusí vždy striktně dodržovat, metoda POST slouží hlavně pro vkládání nových dat.

Metodou GET předáváme data přímo v URL adrese. Pokud bychom ji chtěli u nějaké metody kontroleru vynutit, můžeme použít podobně jako u POST atribut [HttpGet].

Udělejme si jednoduchý příklad použití parametru předaného metodou GET. Kdybychom např. chtěli uvést v URL adrese věnování, pro koho je kalkulačka vytvořena, vypadala by URL adresa takto:

http://localhost:50913/?jmeno=Karla

Případně rozepsaná jako:

http://localhost:50913/Home/Index?jmeno=Karla

Váš port bude samozřejmě opět jiný. Abychom takovouto hodnotu načetli, přesuneme se do první metody Index(), které přidáme parametr. Ten vzápětí předáme pomocí ViewBag pohledu.

public IActionResult Index(string jmeno)
{
        Kalkulacka kalkulacka = new Kalkulacka();
        ViewBag.Jmeno = jmeno;
        return View(kalkulacka);
}

Parametr vypíšeme v pohledu v nadpisu <h2>:

<h2>
        Kalkulacka
        @if (ViewBag.Jmeno != null)
        {
            <text> pro @ViewBag.Jmeno</text>
        }
</h2>

Pokud je GET parametr jmeno zadaný (není null), vypíšeme do nadpisu ještě "pro" a obsah tohoto parametru. Pokud v konstrukci @if vypisujeme nějaký text, měl by být obalený v elementu <text>;

Výsledek:

Kalkulačka
https://local­host:44337/?jme­no=Karla

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ď v URL adrese pomocí metody GET nebo v těle HTTP požadavku pomocí metody POST. POST používají zejména formuláře, GET pokud chceme, aby se hodnota zadávala formou odkazu.

Labely

Popisky u polí formuláře obsahují text s názvem vlastnosti, ke které se váží. Názvy jako Cislo1 však nejsou pro uživatele příliš vábné. Proto k vlastnostem ve třídě Kalkulacka přidáme atributy s lidštějším popisem:

public class Kalkulacka
{
        [Display(Name = "1. číslo")]
        public double Cislo1 { get; set; }
        [Display(Name = "2. číslo")]
        public double Cislo2 { get; set; }
        public double Vysledek { get; set; }
        [Display(Name = "Operace")]
        public string Operace { get; set; }
        public List<SelectListItem> MozneOperace { get; set; }

        // ...

K atributům je třeba nakliknout using System.ComponentModel.DataAnnotations;.

Výsledek:

Kalkulačka v ASP.NET MVC

Validace

Posledním tématem, které si na naší kalkulačce vyzkoušíme, bude validace. Určitě jste již zjistili, že pokud nezadáte číslo nebo by se vám podařilo odeslat místo čísla text, ASP.NET vám formulář odeslat nedovolí. Validace se generují automaticky podle datového typu dané vlastnosti modelu a jsou jak na straně klienta, tak na straně serveru.

Pokud zadáte 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 ta samá validace i na serveru, protože klient si může např. JavaScript vypnout.

Další požadavky na validaci přidáváme ve formě atributů. 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.

U čísel můžeme dále např. validovat jejich rozsah:

[Range(1, 100, ErrorMessage = "Zadejte prosím číslo od 1 do 100.")]

Všimněte si, že u validačních atributů lze jednoduše specifikovat i hlášku, která se uživateli vypíše pokud hodnotu zadá špatně.

U řetězců můžeme validovat např. jejich délku:

např. [StringLength(5)]

Nebo je validovat pomocí regulárních výrazů:

[RegularExpression("\\d+", ErrorMessage = "Neplatný kód")]

Můžete si zkusit, že se hlášky opravdu vypíší. Některé (ku příkladu u vstupních políček pro čísla) jsou vytvářeny automaticky frameworkem pomocí JavaScriptu, nebo si je prohlížeč uzpůsobí sám. Zkuste třeba zadat do pole pro 1. číslo písmena.

Validace v ASP.NET Core MVC

Model kalkulačky je nyní plný atributů a je tedy uzpůsobený hlavně pro View, proto se těmto modelům často říká ViewModel. Toto označení byste měli znát, pokud jste někdy pracovali s WPF.

To by bylo v naší kalkulačce již vše. V příští lekci, Úprava template MVC v ASP.NET Core, začneme něco zajímavějšího. Půjde o osobní blog s administrací. Zdrojové kódy dnešního projektu máte ke stažení níže.


 

Stáhnout

Staženo 37x (1.48 MB)
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?
Ještě nikdo nehodnotil, buď první!
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
Úprava template MVC v ASP.NET Core
Aktivity (5)

 

 

Komentáře

Avatar
Jakub Ondrák:30. června 16:51

Ahoj, ta bublina na poslením obrázku se mi nezobrazuje. Když dám písmeno, tak po opuštění toho pole zmizí. Číslice zůstávají. Možná to bude verzí Windowsů a/nebo IE. Mám Win7

 
Odpovědět 30. června 16:51
Avatar
Martin Petrovaj
Překladatel
Avatar
Odpovídá na Jakub Ondrák
Martin Petrovaj:30. června 16:59

Ahoj, najpravdepodob­nejšia možnosť je tá, že to je záležitosť prehliadača. Ako sa píše v článku, niektoré validačné hlášky a upozornenia si momentálne určuje browser takpovediac sám ("Browsers choose their own error messages and display those errors as they wish, however the jQuery Validation Unobtrusive package can override the messages and display them consistently with others." [1). Screenshoty sú z prehliadača Chrome, je možné, že IE (a iné browsery) to majú trošičku inak, nejaká validácia by ale stále mala fungovať. :-)

Editováno 30. června 16:59
Odpovědět 30. června 16:59
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
Odpovídá na Martin Petrovaj
Jakub Ondrák:30. června 17:04

Jasný, rozumím :-). Teď jsem to zkusil ve Firofoxu, a je to jiný.

Jinak ta validační hláška, že mám zadat číslo od 1 do 100, ta se vždy zobrazí a tím polem? Dá se umístit jinam? Formátovat?

 
Odpovědět 30. června 17:04
Avatar
Martin Petrovaj
Překladatel
Avatar
Odpovídá na Jakub Ondrák
Martin Petrovaj:30. června 17:13

Validačná hláška by sa mala zobraziť tam, kde je v (CS)HTML kóde umiestnený span pre validačné správy:

<span asp-validation-for="Cislo1" class="text-danger"></span>

Čo sa týka formátovania hlášky samotnej, ak využívaš už hotové atribúty z System.Componen­tModel.DataAn­notations (napr. Required, Range, DataType atď), tak tá hláška je onen ErrorMessage, ktorý si môžeš upraviť podľa seba:

[Range(1, 100, ErrorMessage = "Zadejte prosím číslo od 1 do 100.")]

Priznám sa, že som nemal zatiaľ čas ani potrebu skúšať, ako by sa to spravilo, ak by si nad tým chcel nejakú väčšiu kontrolu (napr. aby bola správa dynamická - vypisovala niečo iné napr. v závislosti od nejakej premennej, alebo aby ErrorMessage obsahoval HTML markup), asi by som sa s tým skúsil najprv trochu pohrať, čo všetko to vie out-of-the-box a ak by mi niečo zásadné chýbalo, asi by som išiel do svojho vlastného atribútu.

Odpovědět 30. června 17:13
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
Odpovídá na Martin Petrovaj
Jakub Ondrák:30. června 17:16

Jasný, díky za odpověď a taky dobrej článek :-)

 
Odpovědět 30. června 17:16
Avatar
Bebbana
Člen
Avatar
Odpovídá na Martin Petrovaj
Bebbana:13. července 12:40

Možná by to uměl NuGet balíček Foolproof? Zatím nevím, co vše umí, ale použila jsem jej párkrát, třeba při validaci, které výsledek závisel na na hodnotě jiné vlastnosti, možná to jde i s proměnými.

public bool ImageExists { get; set; } = false;

[RequiredIfFalse("ImageExists", ErrorMessage = "Nahrajte prosím obrázek podpisu.")]
[Display(Name = "Podpis")]
public HttpPostedFileBase UploadedImage { get; set; }
...
 
Odpovědět 13. července 12:40
Avatar
Martin Petrovaj
Překladatel
Avatar
Odpovídá na Bebbana
Martin Petrovaj:13. července 12:57

Foolproof nebol určite zlý, ale už je to dosť starý balíček a navyše nekompatibilný s .NET Core. Samozrejme, sú aj alternatívy, ktoré sú novšie, vo viacerých ohľadoch lepšie a majú aj Core verziu - napr. FluentValidation :-)

V seriáli o tvorbe eshopu, ktorý je vo fáze dokončovania bude dokonca ukázané, ako si vlastné validačné atribúty podobné tým z Foolproof pomocou reflexie napísať ;-)

Odpovědět 13. července 12:57
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
Bebbana
Člen
Avatar
Odpovídá na Martin Petrovaj
Bebbana:13. července 14:44

Díky za tip, s .NET Core pracuju jen chvíli, takže zatím nemám takové zkušenosti.

 
Odpovědět 13. července 14:44
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 8 zpráv z 8.