TOC

This article has been localized into Hungarian by the community.

Modellek:

Egyedi modellhitelesítés

Ha valaha is úgy érzed, hogy a beépített hitelesítési módszerek, amiket az előző cikkben tárgyaltunk, nem elegendőek, akkor az ASP.NET MVC lehetővé teszi, hogy saját hitelesítési logikát írj. Lehetnek szituációk, amikor ez jó ötlet, de érdemes mindig ellenőrizni, hogy nincs-e könnyebben használható, beépített alternatíva, mint a [RegularExpression] lehetőség, ami szintén sokoldalúan használható.

Mindemellett nem különösebben nehéz saját hitelesítési logikát írni. Kétféle módon lehet megközelíteni a problémát, ezért nézzük is meg mindkettőt. Az előző cikkekben látott példákra fogunk építeni, ahol a WebUser osztályt mutattuk be. Teszünk hozzá egy Birthday tulajdonságot, amin aztán egyéni hitelesítést fogunk elvégezni.

Egyéni hitelesítés ValidationAttribute segítségével

Ha a beépítetthez hasonló hitelesítést szeretnél, ahol DataAnnotationöket tehetsz a tulajdonságokhoz (pl. [Required] vagy [EmailAddress]), akkor írhatsz olyan osztályt, ami a ValidationAttribute osztályból ered. Ezután felülírhatod az IsValid() metódust, amibe belefoglalhatod saját hitelesítési logikádat.

Az alábbi példában írtam egy nagyon alapvető hitelesítést az IsValid() metódusba, pusztán a lehetőségeket illusztrálandó. Bizonyos részeket ugyanúgy meg lehetett volna oldani egy [Range] hitelesítéssel, de nem mindet, és ez a hasznos az egyedi hitelesítésben - annyi logikát teszel bele, amennyire csak szükséged van. Minden ellenőrzésre egyéni hibaüzenetet is írhatsz, ahogy azt én is tettem:

public class WebUserBirthdayValidationAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
DateTime birthday = (DateTime)value;
if(birthday.Year < 1900)
    return new ValidationResult("Surely you are not THAT old?");
if(birthday.Year > 2000)
    return new ValidationResult("Sorry, you're too young for this website!");
if(birthday.Month == 12)
    return new ValidationResult("Sorry, we don't accept anyone born in December!");
return ValidationResult.Success;
    }
}

Több ellenőrzést hajtunk itt végre, és mindegyiknél a ValidationResult osztály új példányát térítjük vissza, ha a feltétel igaz. Ha egyik sem igaz, akkor feltételezhetjük, hogy valós az érték, úgyhogy visszatéríthetjük a ValidationResult.Success értéket. Ezt a hitelesítési logikát ugyanúgy használhatjuk a WebUser osztály Birthday tulajdonságán, mint a beépített hitelesítési mechanizmusokat:

public class WebUser
{
    // Other properties here...
   
    [WebUserBirthdayValidationAttribute]
    public DateTime Birthday { get; set; }
}

Ha tesztelni akarod ennek működését, akkor szükséged lesz egy vezérlőre ami GET és POST kéréseket is kezelni tud, valamint egy nézetre, ami tartalmazza a megfelelő űrlapot:

public class ValidationController : Controller
{
    [HttpGet]
    public IActionResult CustomValidation()
    {
return View();
    }

    [HttpPost]
    public IActionResult CustomValidation(WebUser webUser)
    {
if(ModelState.IsValid)
    return Content("Thank you!");
else
    return View(webUser);
    }
}
@model HelloMVCWorld.Models.WebUser
@using(var form = Html.BeginForm())
{    
    <div>
@Html.LabelFor(m => m.Birthday)
@Html.TextBoxFor(m => m.Birthday)
@Html.ValidationMessageFor(m => m.Birthday)
    </div>

    <input type="submit" value="Submit" />
}

Gratulálok, ezzel meg is írtad saját hitelesítési módszeredet.

Ennek a megközelítésnek az egyik nagy előnye, hogy a hitelesítési logika nem feltétlen kötődik egy bizonyos modellhez - ahelyett, hogy WebUserBirthdayValidationAttributenak neveznéd az osztályt, hívhatnád BirthdayValidationAttributenak, majd felhasználhatod más születésnappal kapcsolatos tulajdonságokon is az egész projektben. Lesznek viszont helyzetek, amikor teljesen logikus modellhez kötni a hitelesítési módszeredet - ezt fogjuk következőnek szemügyre venni.

Egyéni hitelesítés IValidatableObjecttel

A fenti, ValidationAttribute-alapú megközelítés helyett azt is megtehetjük, hogy a modellünk megvalósítja az IValidatableObject felületet. Ezzel közvetlen a modellbe helyezhetjük a hitelesítési logikát ahelyett, hogy új osztályt írnánk erre. Ez különösen vonzó lehet, ha a hitelesítés egynél több tulajdonságot érint, mivel az így nem közvetlen egy bizonyos tulajdonsághoz van kötve.

Az IValidatableObject felület egyetlen metódussal rendelkezik: Validate(). Ez kell tartalmazza az összes logikát, amit nem tudsz tulajdonságokra alkalmazni a beépített lehetőségeken keresztül. Más szavakkal, itt is szabadon keverheted az egyedi és szokványos hitelesítést. Az alábbi, WebUserValidatable nevű osztályban pontosan ezt is tettük (de jegyezd meg, hogy nem szükséges a "Validatable" szót belefoglalni az osztály nevébe - úgy hívhatod, ahogy csak szeretnéd):

public class WebUserValidatable : IValidatableObject  
{  
    [Required(AllowEmptyStrings = true, ErrorMessage = "You must enter a value for the First Name field!")]  
    [StringLength(25, ErrorMessage = "The First Name must be no longer than 25 characters!")]  
    public string FirstName { get; set; }  

    [Required(ErrorMessage = "You must enter a value for the Last Name field!")]  
    [StringLength(50, MinimumLength = 3, ErrorMessage = "The Last Name must be between 3 and 50 characters long!")]  
    public string LastName { get; set; }  

    public DateTime Birthday { get; set; }  

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)  
    {  
if(this.Birthday.Year < 1900)  
    yield return new ValidationResult("Surely you are not THAT old?", new[] { "Birthday" });  
if(this.Birthday.Year > 2000)  
    yield return new ValidationResult("Sorry, you're too young for this website!", new[] { "Birthday" });  
if(this.Birthday.Month == 12)  
    yield return new ValidationResult("Sorry, we don't accept anyone born in December!", new[] { "Birthday" });  
    }  
}

Két dolog fog feltűnni - a logika, amit írtam lényegében ugyanaz, mint ami a ValidationAttribute példában is volt, pár különbséggel. Az egyik az, hogy nem kell semmit sem visszatérítenünk ha a hitelesítés sikeres. A másik, hogy a tulajdonság nevét (vagy többét, ha többről van szó) belefoglaljuk a hibaüzenetbe, ez esetben azt, hogy Birthday. Az ok egyszerű: ha a hitelesítés nem egy bizonyos tulajdonsághoz kötődik, DataAnnotationökön keresztül, akkor a keretrendszer azt sem tudja megállapítani, hogy a hiba melyik tulajdonsághoz kötődik, ezért nekünk kell ezt megadnunk. Ez lehetővé teszi azt is, hogy több tulajdonságot felöleljen a hitelesítés:

if((this.Birthday.Month == 12) && (this.FirstName != "Santa"))
    yield return new ValidationResult("Sorry, to be born in December, we require that your first name is Santa!", new[] { "Birthday", "FirstName" });

Bár komolytalan a fenti példa, jól mutatja, hogy milyen könnyen tudsz egy vagy több hitelesítési ellenőrzést egyszerre több tulajdonságra vonatkoztatni. Ha a nézetben használod a beviteli mezőkhöz tartozó hibaüzenetek megjelenítését, akkor a generált hibaüzenet mindkét beviteli mezőn rajta lesz.

Ha ezt működés közben szeretnéd látni, csak tegyél a projektedbe egy vezérlőt és egy megfelelő nézetet, űrlappal:

public class ValidationController : Controller
{
    [HttpGet]
    public IActionResult CustomValidation()
    {
return View();
    }

    [HttpPost]
    public IActionResult CustomValidation(WebUserValidatable webUser)
    {
if(ModelState.IsValid)
    return Content("Thank you!");
else
    return View(webUser);
    }
}
@model HelloMVCWorld.Models.WebUserValidatable
@using(var form = Html.BeginForm())
{
    <div>
@Html.LabelFor(m => m.FirstName)
@Html.TextBoxFor(m => m.FirstName)
@Html.ValidationMessageFor(m => m.FirstName)
    </div>

    <div>
@Html.LabelFor(m => m.LastName)
@Html.TextBoxFor(m => m.LastName)
@Html.ValidationMessageFor(m => m.LastName)
    </div>

    <div>
@Html.LabelFor(m => m.Birthday)
@Html.TextBoxFor(m => m.Birthday)
@Html.ValidationMessageFor(m => m.Birthday)
    </div>

    <input type="submit" value="Submit" />
}

Összefoglalás

A saját, egyedi ellenőrzési logikád megírása könnyű feladat ASP.NET MVC-ben. Két módja van neki, az egyik, amelyik közvetlen egy tulajdonsághoz kapcsolódik, és egy másik, amelyik modellhez kapcsolódik, lehetővé téve, hogy több tulajdonságot is hitelesíts egyszerre.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!