Bevezetés
Sok esetben a fejlesztők munkájának nagy százalékát a felhasználói input validálása teszi ki. Nézzük meg most, milyen megoldásokat kínál számunkra ilyen témakörben az ASP.NET.
.NET és a Validátorok
Webalkalmazás esetén a felhasználóktól érkező értelmetlen adatokat két helyen is van
lehetőségünk megvizsgáltatni.
Az egyik értelemszerűen a szerveroldal, ahol végig
iterálhatunk a felhasználóktól kapott adatokon, majd kiírhatunk valamilyen hibaüzenetet.
A másik lehetőség a kliensoldal, ahol java script segítségével
még az előtt lekezelhetjük a problémát, mielőtt rákattinthatnának a küldés
gombra.
A .NET Framework-től 5 olyan vezérlőt kapunk, melyek képesek mindkét oldalon
adatellenőrzésre (validálásra).
Ezeket együttesen Validátoroknak hívjuk.
Ilyenkor jön a kérdés:
Mi értelme van szerveroldalon még egyszer validálni, ha már egyszer
kliens oldalon ezt megtettük? A válasz egyszerű, azért mert a java-s ellenőrző kódok
egyszerően kijátszhatóak.
A felhasználótól érkező primitív adatot, akkor nevezzük valid-nak (érvényesnek), ha megfelel
az általunk kitalált, szinte már teljesíthetetlen, követelményeknek. Ilyen magas szintű
elvárásokra gondoljunk, pl.: számot írjon be az életkorához, ne szöveggel próbálja meg leírni.
Az érvénytelen adatokról kétféleképpen is értesíthetjük a felhasználót.
Az egyik lehetőség az,
hogy közvetlen a szövegdobozok mellé helyezzük el a validátor vezérlőket, és ha invalid
értéket ad meg a kliens valamelyik textbox-ba, akkor amellett pirossal meg fog jelenni egy
figyelmeztetés. Ilyennel már biztos mindenki találkozott, például regisztrációs űrlapnál: "a
jelszó nem megfelelő formátumban van, tartalmaznia kell...".
A másik lehetőség az, hogy a
figyelmeztetéseket (hibaüzenteket) összegyűjtjük és egy adott helyen felsoroljuk őket. Ez
azért lehet sokszor hasznos, mivel a hosszabb hibaüzentek miatt szétcsúszhat az oldal, vagy
egyszerűen csak nem úgy lett tervezve a design, hogy ott bármilyen egyéb szöveg is elférjen.
Ilyenkor általában egy joker (*) karaktert szokás használni figyelmeztetésként, hogy
valahogyan mégis megjelöljük a kliensnek, melyik szövegdoboz a problémás.
Az érvényesség kiértékelés kliensoldalon kétféle esemény hatására hívódhat meg. Az egyik
lehetőség, hogy az adott textbox elveszti a fókuszt (pl.: a következő szövegdobozba kattintunk). A
másik kiváltó ok az lehet, ha pl.: valamelyik gombra rákattintunk (postback-et generálunk).
Validátorok használata
A példaalkalmazásban az alábbi pár adatot
fogjuk elkérni a felhasználóktól: Cím, Irányítószám, Életkor illetve E-mail cím. Az ezen infókat
bekérű szövegdobozok mindegyikéhez hozzá fogunk rendelni egy-egy különböző validátort,
és így használat közben ismerkedünk meg velük.
RequiredFieldValidator
Ha magyarosítani szeretnénk a RequiredFieldValidator vezérlő nevét, akkor a legtalálóbb
fordítás a kötelező mezőérvényesítő lenne.
Mint ahogyan a nevéből is következik, ezen
validatorral azt követelhetjük meg a felhasználótól, hogy egy adott textbox-ot ne hagyjon
üresen (vagyis mindenféleképpen írjon bele valamit).
Jelenesetben a szállítási cím
nélkülözhetetlen számunkra, ezért ezt az információt megköveteljük a megrendelőtől.
A címet egy txtbox_address nevű szövegdobozba kérjük be, és közvetlenül mellette
helyezzünk el egy RFV-t, melyet az alábbi módon állítsunk be:
< asp:TextBox ID="txtbox_address" runat="server" Width="250px" >
< /asp:TextBox >
< asp:RequiredFieldValidator
ID="rfv_address"
runat="server"
ControlToValidate="txtbox_address"
ErrorMessage="Kérlek töltsd ki az alábbi mezot, add meg a szállítási címet!" >
< /asp:RequiredFieldValidator >
Minden egyes validátor vezérlő egy úgynevezett BaseValidator ősosztályból van
származtatva, melyből az alábbi pár tulajdonságot öröklik:
- ControlToValidate: Ezen tulajdonság segítségével szabhatjuk meg, hogy a validátor, mely
textbox-ra ügyeljen, vagyis melyik szövegdoboz értékét figyelje.
- ErrorMessage: Itt a hibaüzenetet állíthatjuk be, vagyis hogy mi jelenjen meg akkor a
textbox mellett, ha invalid az értéke. Felhasználóbarátabb megoldás, ha itt inkább
figyelmeztetéseket, leírásokat adunk meg, mint ha vicces hibaüzenetekkel próbálkoznánk (pl.:
nullreference exception).
- Display: Egy szövegdobozhoz több validator vezérlő is rendelhető. Ilyen esetekben jön jól a
Display tulajdonság, mely segítségével azt tudjuk szabályozni, hogy a hibaüzenetek helye
rögzített legyen-e vagy sem. Ha rögzített (vagyis Static), akkor a hibaüzenetek pontosan ott
fognak megjelenni, ahova tettük a validator vezérlőket. Vagyis ha két validator közül csak a
másodiknál nem teljesülnek a kritériumok, akkor az első validátornak lefoglalt hely ott fog
tátongani a textbox és a hibaüzenet között. Ezt úgy tudjuk elkerülni, hogy a Display
tulajdonságot Dynamic-ra állítjuk.
- IsValid: Itt arról kaphatunk információt, hogy a ControlToValidate-nél megadott
szövegdobozban lévő adat érvényese. Értelemszerűen ennek a tulajdonságnak csak a kódból
történő lekérdezéskor van értelme.
- EnabledClientSideScript: Ezzel engedélyezhetjük, hogy a validator vezérlőnk már kliens
oldalon is megvizsgálja az input adatokat, vagy csak szerveroldalon álljon neki az
ellenőrzésnek. Alapértelmezetten mindkét oldalon történik validálás, vagyis a default értéke
true.
A RFV vezérlőnek az egyetlen egyedi tulajdonsága, mely hasznos lehet: az IntialValue.
Ezzel egy kezdőértéket állíthatunk be, melytől el kell térnie a textbox-ba beírt adatnak.
Alapértelmezetten ez a String.Empty-vel egyezik meg.
RangeValidator
A RangeValidator, vagyis magyarul a tartomány érvényesítő, arra használható, hogy a
kliens által bevihető értékeket egy intervallum közé zárjuk. Az int. mindenesetben zárt, vagyis
a két szélsőértéket is érvényesnek tekinti a validátor.
A példaalkalmazásunkban az irányítószámra szeretnénk alsó, illetve felső korlátot megszabni.
Magyarországon az irányítószámoknak 4 számjegyből kell állnia, ezért a teljesség igénye
nélkül, ha az értékeket 1000 és 9999 közé zárjuk, akkor érvényesnek tekintjük az input adatot.
Nézzük is meg, hogyan valósíthatjuk meg mindezt a RangeValidator segítségével:
< asp:TextBox ID="txtbox_postcode" runat="server" Width="30px" > < /asp:TextBox >
< asp:RangeValidator
ID="rv_postcode"
runat="server"
ControlToValidate="txtbox_postcode"
ErrorMessage="Az irányítószám 4 számjegyből áll!"
MaximumValue="9999"
MinimumValue="1000"
Type="Integer">
< /asp:RangeValidator >
A Type a legfontosabb tulajdonság az összes közül, ugyanis ezzel tudjuk megszabni, milyen
típusú adatot várunk a felhasználótól, vagyis milyen értékek lehetnek az intervallumon belül.
A RangeValidator által elfogadott típusok:
- String = szöveg
- Integer = egészszám
- Double = 64bit-es lebegőpontos szám
- Date = dátum
- Currency = pénznem (System.Decimal + pénznem szimbólumok és elválasztó karakterek).
Fontos, hogy ne felejtsük el beállítani a Type-ot, mivel alapban String értéket vesz fel!
A Maximum- illetve MinimumValue tulajdonságok segítségével a két szélsőértéket
határozhatjuk meg, ügyelve a Type-nál beállított típusra. Ha véletlen a maximumértéket
alacsonyabbra állítjuk, mint a minimumérték, akkor csak futásidőben kapunk róla
figyelmeztetést.
CompareValidator
Az összehasonlító érvényesítő-vezérlővel kétfajta ekvivalencia vizsgálatot végeztethetünk
el. Az egyik, amikor két textbox értékét hasonlíttatjuk össze, a másik pedig, amikor egy
szövegdobozt egy valamilyen konstans értékkel.
A mostani alkalmazásunkban a második verzióra lesz szükségünk a felhasználó által beírt
életkor ellenőrzéshez (idősebbnek kell lennie, mint 18).
Ellenőrizzük le, miként állíthatjuk ezt
be:
< asp:TextBox ID="txtbox_age" runat="server" Width="30px" > < /asp:TextBox >
< asp:CompareValidator
ID="cv_age"
runat="server"
ControlToValidate="txtbox_age"
ErrorMessage="Csak 18 éven felüliek rendelhetnek!"
Operator="GreaterThan"
Type="Integer"
ValueToCompare="18" >
< /asp:CompareValidator >
Itt is a Type az egyik legfontosabb tulajdonság. (Mindkét validátor a BaseCompareValidator
osztályból származik).
Egy másik szintén fontos property: az Operator, mely azt szabja meg,
hogy milyen logikai kifejezésnek kell teljesülnie a két érték között. Ezen tulajdonság által
felvehető értékek:
- Equal: egyenlők-e
- NotEqual: nem egyenlők-e
- GreaterThan: nagyobb-e
- GreaterThanEqual: nagyobb egyenlő-e
- LessThan: kisebb-e
- LessThanEqual: kisebb egyenlő-e
- DataTypeCheck: megegyezik-e a típusuk
A CompareValidator a ControlToValidate-nél megadott textbox-ot hasonlítja össze az
Operator-nál megszabott szempont szerint, vagy a ControlToCompare-nél beállított
szövegdobozzal, vagy pedig a ValueToCompare-ben lévő konstanssal.
RegularExpressionValidator
A reguláris kifejezést érvényesítő vezérlő az egyik legszélesebb körben használható
validátor, hiszen regexp-szel szinte mindent le lehet írni.
A reguláris kifejezések lelki világába
most nem szeretnék elmélyedni, ezért akit érdekel, hogy miként kell összeállítani egy
expression-t az alábbi címek valamelyikén nézhet utána ennek:
http://regexplib.com
http://mycroft.web.elte.hu/06_linux_regexp.html
A példaalkalmazásunkban az e-mail címet szeretnénk leellenőriztetni, hogy tényleg e-mail
cím-e. Ily módon valósíthatjuk meg:
< asp:TextBox ID="txtbox_mail" runat="server" Width="200px" >
< /asp:TextBox >
< asp:RegularExpressionValidator
ID="rev_mail"
runat="server"
ControlToValidate="txtbox_mail"
ErrorMessage="Érvénytelen e-mail cím!"
ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" >
< /asp:RegularExpressionValidator >
A ValidationExpression tulajdonságon keresztül adhatjuk meg a pattern-t, amelyre le
szeretnénk ellenőriztetni a textbox-ot.
Mivel nem mindenki mozog otthonosan regexp-ekben, és ezt a
.NET fejlesztői is tudják, ezért a Visual Studio tartalmaz egy jó pár előredefiniált sablont.
Ezek között a property ablakban a ValidationExpression tulajdonság melletti ... gombra való
kattintás után előugró Regular Expression Editor ablakban válogathatunk.
CustomValidator
A CustomValidator (egyedi érvényesítő) kilóg a többi validátor közül, ugyanis itt nekünk kell
megírnunk az érvényességellenőrző kódokat (vagyis nincsenek előredefiniált szabályok).
A
kliensoldali validálófüggvény nevét a ClientFunctionName-nél kell megadnunk.
A függvény két
paramétert kap egy source-ot (a validátorra egy referenciát), illetve egy arguments-et
(melynek a value tulajdonságán keresztül tudjuk elérni a textbox-ba írt szöveg).
A függvényünknek nem kell, hogy legyen visszatérési értéke, ezért nekünk kell java kódból
beállítanunk az IsValid tulajdonságot vagyis, hogy mikor érvényes az input.
A dolog
érdekessége, hogy az IsValid nem a source-n keresztül érhető el, hanem az arguments-en!
A szerveroldali érvényességellenőrzés valamivel egyszerűbben megoldható, hiszen van egy
külön ServerValidation nevű eseménye a CustomValidator-nak, amelyre csak fel kell
iratkoznunk.(Itt is szintén az arguments-en keresztül kell beállítani az
IsValid értékét).
A CustomValidator vezérlőnek még egy tulajdonságával meg kell ismerkednünk, még pedig a
ValidateEmptyText-tel.
Ez azért fontos számunkra, mivel a validátor vezérlők (kivéve a
RequiredFieldValidator-t) az üresen hagyott szövegdobozokat valid-nak tekintik! Vagyis ha
minden mezőt ki akarunk töltetetni a felhasználóval, akkor minden szövegdoboz mellé el kell
helyeznünk egy RFV-t is. Ne felejtsük el ilyenkor beállítani a Display tulajdonságokat!
Tehát a ValidateEmptyText arra való, hogy egy felesleges RFV-től megkíméljük magunkat.
Ehhez true-ra kell állítanunk az értékét (alapban false).
Ilyenkor értelemszerűen a szerver
vagy kliens oldali kódunkban nekünk kell leellenőriznünk a szövegdoboz text-jének hosszát.
ValidationSummary
Mint ahogyan már fentebb is volt róla szó, a hibaüzeneteket kétféleképpen lehet
megjeleníteni, vagy a textbox-ok mellett, vagy pedig egy adott helyen összegyűjtve őket. Az
első lehetőség az alapértelmezett, tehát nem kell semmilyen extra kód. A másodiknál viszont
már szükségünk lesz egy új vezérlőre, amely összegyűjti helyettünk a hibaüzeneteket és
felsorolja őket. Erre a célra a ValidationSummary (érvényesítési kivonat) vezérlőt találták ki.
Így kell beállítanunk egy ilyet:
< asp:ValidationSummary
ID="val_summ"
runat="server"
Enabled="False"
ShowMessageBox="True"
DisplayMode="List"
HeaderText="
< u >
Hibaüzenetek:
< /u >
< br > "
/ >
A DisplayMode tulajdonságon keresztül a felsorolás típusát szabhatjuk meg.
Ha List-re
állítjuk, akkor egyszerűen csak felsorolja egymás alatt a hibaüzeneteket.
Ha BulletedList-re,
akkor pontokat is tesz az errormessage-k elé, ha pedig SingleParagraph-ra, akkor pedig egy
sorba fogja megjeleníteni őket.
A ShowMessageBox segítségével azt szabályozhatjuk, hogy a hibaüzenetek egy alert
üzenetablakban jelenjenek-e meg, vagy ne. Alapértelmezetten false az értéke.
Ennek van egy párja, a ShowSummary, mellyel az oldalon történő megjelenítést
kapcsolgathatjuk ki, illetve be. Értelemszerűen egyszerre csak az egyiket állítsuk true-ra!
A HeaderText tulajdonság, mint ahogyan a nevéből is következik, fejlécszöveg megadására
használható.
Fontos, hogy az ide beírt html tagek csak az oldalon való megjelenítésnél
kerülnek feldolgozásra, ShowMessageBox esetén nem!
Az alábbi pár dolgot kell beállítanunk kódból:
if (cb_summary.Checked)
{
val_summ.Enabled = true;
rfv_address.Text = "*";
cv_age.Text = "*";
rv_postcode.Text = "*";
rfv_address.Text = "*";
}
else
{
val_summ.Enabled = false;
rfv_address.Text = String.Empty;
cv_age.Text = String.Empty;
rv_postcode.Text = String.Empty;
rfv_address.Text = String.Empty;
}
Konkrétan azt állítjuk be a CheckedChanged eseménykezelőjében, hogy ha engedélyezzük a
ValidationSummary-t, akkor a szövegdobozok mellett egy joker karakter jelenjen meg, ne a
teljes hibaüzenet. Ha nincs bepipálva, akkor pedig kitörljük a Text-ek értékét és ilyenkor az
ErrorMessage-beli figyelmeztetések fognak ismét megjelenni az oldalon.
Még egy dologra van szükségünk a példaalkalmazásunkhoz, hogy teljesen kész legyen, mégpedig egy gomb.
Ennek a click eseményéhez az alábbi parányi kódrészletet rendeljük:
if (!IsValid) return;
lbl_summary.Visible = true;
A Page osztályon keresztül érhetjük el az IsValid tulajdonságot, mely segítségével
megbizonyosodhatunk szerveroldalon is arról, hogy minden validator érvényesnek találta az
input adatokat.
A Page-ből indirektbe is meg tudjuk kérni az összes validátort, hogy
validáljon, a Validate metódus segítségével.
Az oldalon elhelyezett validátorok gyűjteményét
pedig a Validators tulajdonságon keresztül érhetjük el.
El is készültünk a példaalkalmazással.
Néhány hasznos tulajdonság
Összesen három érdekes tulajdonságra szeretném még felhívni a figyelmet a validator
vezérlőkkel kapcsolatban:
SetFocusOnError, CauseValidation, ValidationGroup.
- SetFocusOnError: Ez egy ASP.NET 2.0-ban debütált új szolgáltatáshoz tartozó
tulajdonság, mely segítségével a fókuszt automatikusan a textbox-ra állíttathatjuk,
amennyiben a validátor jelez, hogy invalid értéket "talált".
Ha több validátornál is igazra
állítjuk ezt az értéket, akkor mindig az oldalhierarchiában lévő legelső érvényesítő-vezérlőhöz
kapcsolt szövegdobozra fog ugrani a fókusz (kurzor).
- CauseValidation: Ezen tulajdonság kicsit eltér a másik kettőtől, ugyanis ez a property nem
a validátor vezérlők tulajdonságai közé tartozik, hanem a gombéhoz.
Emlékezzünk vissza, a
kliensoldali validáltatást mindenféle PostBack-et generáló esemény kiválhat. De ez nem
minden esetben jó. Például egy regisztrációs űrlapnál szokás kitenni egy Mégse gombot is,
azok számára, akik mégis meggondolnák magukat. Azonban ilyenkor nem várhatjuk el a
felhasználótól, hogy bármit is kitöltsön, vagy hogy mindegyik textbox valid legyen. Ezért ha a
CauseValidation-t false-ra állítjuk a Mégse gombnál, akkor nem fognak meghívódni
kliensoldalon az ellenőrző rutinok, ha rákattint a kliens, hanem simán postbackel az oldal.
- ValidationGroup: Szintén egy ASP.NET 2.0-s új feature, mely segítségével csoportokba
szervezhetjük a validátor vezérlőinket. Ez azért lehet sokszor hasznos, mivel ilyenkor nem a
teljes oldalon lévő összes textbox kerül kiértékelésre, hanem csak az adott gombbal egy
csoportban lévő validátorokhoz kapcsolódóak. (Természetesen ilyenkor a szerveroldali
IsValid ellenőrzésnél is csak az adott ValidationGroup-ban lévő validátorok játszanak!)
Tehát nem csak az érvényesítő-vezérlőknek van ilyen tulajdonsága, hanem a gomboknak is!