ASP.NET MVC remote validation

A model validation az egyik kedvencem az ASP.NET MVC-ben. Egy helyre kerül minden, ami a validáláshoz kell, ráadásul a jQuery validationnek köszönhetően a beépített “validátorok” nagyon jól működnek kliens oldalon is.

Legyen mondjuk egy klasszikus Person modell osztályunk, amire könnyen felaggathatom a validálási szabályokat leíró attribútumokat:

public class Person
{
    [DisplayName( "E-mail cím:" )]
    [Required( ErrorMessage = "Az e-mail cím megadása kötelező! ")]
    public string Email { get; set; }

    [DisplayName( "Felhasználónév:" )]
    [Required( ErrorMessage = "A felhasználónév megadása kötelező! " )]
    public string UserName { get; set; }

    [DisplayName( "Jelszó:" )]
    [Required( ErrorMessage = "A jelszó megadása kötelező! " )]
    public string Password { get; set; }
}

A view-ba pedig csak @Html.ValidationMessageFor hívások kellenek a hibaüzenetek megjelenítéséhez (amiket egyébként a VS le is generál magától):

@using( Html.BeginForm() )
{
    @Html.ValidationSummary( true )
    <fieldset>
        <legend>Regisztráció</legend>
        <div class="editor-label">
            @Html.LabelFor( model => model.Email )
        </div>
        <div class="editor-field">
            @Html.EditorFor( model => model.Email )
            @Html.ValidationMessageFor( model => model.Email )
        </div>
        <div class="editor-label">
            @Html.LabelFor( model => model.UserName )
        </div>
        <div class="editor-field">
            @Html.EditorFor( model => model.UserName )
            @Html.ValidationMessageFor( model => model.UserName )
        </div>
        <div class="editor-label">
            @Html.LabelFor( model => model.Password )
        </div>
        <div class="editor-field">
            @Html.EditorFor( model => model.Password )
            @Html.ValidationMessageFor( model => model.Password )
        </div>
        <p>
            <input type="submit" value="Mehet" />
        </p>
    </fieldset>
}

A helyzet akkor kezd bonyolódni, amikor kliens oldalon szeretnénk validálni, de az input ellenőrzési logika vagy a hozzá szükséges egyéb adatok szerver oldalon vannak, például egy adatbázisban. Még kellemetlenebb a helyzet, ha ráadásul nem is egyetlen mező értékét kell ellenőriznünk, hanem több adat együttállását kell vizsgálnunk. Ezt megoldhatnánk egy postback után a controllerben, de sokkal felhasználóbarátabb, ha Ajaxosan oldjuk meg, hiszen így már az űrlap kitöltése közben tudjuk figyelmeztetni a felhasználót, hogy javítsa ki a beírt értékeket. Szerencsére erre a problémára van közvetlen megoldás az ASP.NET MVC-ben, úgy hívják, hogy remote validation. Így kell beizzítani:

A modellben adjunk egy Remote attribútumot a validálandó mezőhöz:

[Remote( "ValidateUserNameAndEmail", "Home", AdditionalFields = "Email" )]
public string UserName { get; set; }

Itt meg kell adnunk, hogy melyik controller action lesz az Ajax hívás szerver oldali végpontja. Ha több mező értékére van szükségünk szerver oldalon, akkor használhatjuk az AdditionalFields paramétert. A fenti példában a validálás akkor fog megtörténni, amikor a UserName mező értéke megváltozik és a szerverhez el fog jutni az Email mező értéke is, az esetleges hibaüzenet pedig a UserName mező mellett fog megjelenni. Szerencsére semmi akadálya annak, hogy ugyanezt az attribútumot ráakasszuk az Email mezőre is, AdditionParameterkent a UserName mezőt adva meg.

Már csak a hivatkozott controller actiont kell megírnunk, például így:

[OutputCache( NoStore = true, Location = OutputCacheLocation.None )]
public JsonResult ValidateUserNameAndEmail( string userName, string email )
{
    return this.IsValid( userName, email ) ? 
        this.Json( true, JsonRequestBehavior.AllowGet ) : 
        this.Json( "Ezzel a névvel és e-mail címmel már létezik regisztráció!", 
            JsonRequestBehavior.AllowGet );
}

A valódi ellenőrző logikát áttettem egy IsValid függvénybe, hogy itt ne zavarjon. A lényeg:

  • Klasszikus controller action azokkal a paraméterekkel, amiket ellenőrizni szeretnénk. Ha van a modellben AdditionalFields, akkor mindet.
  • Válaszként egy JsonResult típussal kell visszatérnünk.
  • Ha az adat helyes, akkor a válasz true, ha hibás, akkor a hibaüzenet.
  • Meg kell adni a JsonRequestBehavior.AllowGet paramétert, anélkül nem fog menni.
  • Célszerű az OutputCache-t kikapcsolni, hogy a böngésző ne gyorsítótárazza a választ.

A hibaüzenet a Html.ValidationMessageFor helyén fog megjelenni, tehát a view-n nem kell változtatnunk. Ha nem a Studio generálta a markupot, hanem mi írtuk, akkor arra érdemes figyelni, hogy legyen benne Html.BeginForm, mezei <form> elemre tapasztalataim szerint nem működik.

Mindössze ennyi, az Ajaxos bűvészkedést az ASP.NET megcsinálja helyettünk. Íme az eredmény:

aspnet-mvc-remote-validation

Akit szeretné lerántani a leplet a varázslatról, az nézze meg a generált markupban a data-val-remote- attribútumokat és figyelje meg a HTTP forgalmat például Fiddlerrel. Érdemes!

 

Technorati-címkék: ,,,,,

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s