Všude tam, kde uživatel zadává nějaké údaje do aplikace, je potřeba tyto údaje před dalším zpracováním řádně zvalidovat, tedy ověřit jejich platnost (validitu). Je třeba si uvědomit, že validace existuje na různých úrovních. Pro účely tohoto článku nám bude stačit, když budeme rozlišovat mezi vstupní validací a business validací (více o validacích).
Vstupní validace je první z validací, které se provádějí, a de facto se jedná o kontrolu, že zadaný údaj je správného datového typu. Např. když uživatel zadá do pole „Počet produktů“ hodnotu „fgh„, neprojde vstupní údaj touto validací. Použití této validace bývá velice jednoduché, neboť primitivních datových typů je omezená množina, a je tak velká pravděpodobnost, že to už někdo naprogramoval a zveřejnil, a my máme k dispozici minimálně nějakou inspiraci. Jedna z mála záludností, která zde na nás může číhat, jsou různé národní zvyklosti, konkrétně mám na mysli desetinné tečky/čárky a různé zápisy data.
Vstupní validace bývá často dokonce až tak jednoduchá, že se u webových aplikací vyplatí ji provádět už na klientovi pomocí JavaScriptu (např. pomocí nějaké pěkného pluginu do jQuery), což s sebou nese hned dvě výhody – uživatel má okamžitou odezvu a můžeme tím snížit zátěž serveru (protože nemusí zpracovávat špatná data). Samozřejmě na JavaScript se nedá spoléhat, takže je potřeba vždy validovat i na straně serveru.
Všechny další přesnější druhy validací, které už pracují s hodnotou v odpovídajícím datovém typu, budeme nazývat business validace. Jedná se např. o ověření rozsahu zadaného čísla, minimální/maximální délky vstupu, povinnosti zadat hodnotu, regexpu, kterým musí zadaný vstup projít (vhodné pro telefonní čísla, e-maily, PSČ, …). I tato ověření se dají často provést jednoduše pomocí JavaScriptu.
Dosud se tedy jednalo o ověření jedné samostatné hodnoty, např. „musí to být číslo mezi 1 a 5 a musí být vždy uvedené„. Většinou ale dochází k zadání více hodnot, které navíc mohou mít mezi sebou určitý vztah, který je také nutné/vhodné zvalidovat, tedy ověřit konzistenci zadaných hodnot (např. když člověk zaškrtne, že chce posílat novinky pomocí SMS, tak musí zadat číslo telefonu). I tato validace se dá duplikovat na straně klienta pomocí JavaScriptu, ale často už musíme napsat vlastní validační JavaScript, který je potřeba udržovat ve stejné verzi vůči validaci na serveru, proto bych se já osobně této validaci na straně klienta spíše vyhnul.
Kde validovat
Toto téma jsem nakousl už v předchozích odstavcích. Je vhodné provádět alespoň základní validaci vstupních dat u klienta pomocí JavaScriptu, čímž dáme uživateli okamžitou odezvu a navíc můžeme odlehčit serveru. Osobně bych na straně klienta prováděl jen tu validaci, jejíž kód je možný automaticky nagenerovat z business objektů. To proto, abych se vyhnul udržování téhož kódu na dvou místech (jednou v JavaScriptu, podruhé v business logice).
A co na straně serveru? Zde záleží na tom, jak máme implementovánu business vrstvu. Často to bývají třídy, kterým se přes properties nastaví nějaké hodnoty a pak se zavolá metoda, která tato data zpracuje. Budu tedy předpokládat nějakou takovou business vrstvu aplikace.
Nejprve tedy potřebujeme nastavit properties nějakého business objektu. Zde se logicky dostává ke slovu vstupní validace, protože je nutné překonvertovat vstupní data ze stringů do odpovídajícího datového typu. Dále je třeba ověřit, zda zadaná hodnota splňuje požadovaná kritéria (např. že je číslo v určitém rozsahu). Zde velmi záleží, jak máme implementovanou business vrstvu. Při přiřazení neplatné hodnoty do property můžeme např. vyvolat v setteru výjimku – to je typické pro aplikace, kde je business vrstva založena na Entity Frameworku či třídách z LinqToSql.
Pokud ale budeme mít validace v business objektech implementované pouze takto imperativně, připravíme se o možnost automaticky generovat validační JavaScriptový kód. Proto může být vhodné specifikovat validace také deklarativně, v případě C# odekorovat properties business tříd atributy, které budou specifikovat, jaké hodnoty lze do properties přiřadit. Tyto atributy pak není problém přečíst a nagenerovat z nich odpovídající JavaScriptový validační kód – ten je ale samozřejmě možné generovat už na základě znalosti datového typu properties. Co víc, pokud použijeme nějaký vhodný nástroj (např. PostSharp), můžeme mít velkou část validací specifikovanou JEN deklarativně, protože tento nástroj nám vygeneruje odpovídající validační kód i na straně serveru.
Komplexní validace, která kontroluje konzistenci zadaných dat, bývá součástí business metody, která provádí vlastní zpracování vstupních dat, a netřeba ji nějak speciálně řešit. V případě problémů prostě business metoda vyvolá výjimku.
Článek měl za cíl popsat, jaké typy validací existují a kde je vhodné je provádět. V pokračování ukáži, jak přistoupit k validaci v ASP.NET MVC aplikaci, což bude mj. vyžadovat znalost model-binderu, takže i o něm bude další článek.