MVC Custom Validation mit IValidatableObject Interface


Letzte Woche wurde ich auf ein Interface aufmerksam gemacht, welches ich bisher in MVC noch nicht benutzt habe. Dabei handelt es sich um das IValidatableObject Interface, mit diesem Interface kann man sehr einfach alle möglichen und komplexen Validierungen für sein Model einbinden. Die Daten können dann an geeigneter Stelle mit “ModelState.IsValid” geprüft werden.

Dafür muss im Model nur das Interface “IValidatableObject” eingebunden werden und mit dem Interface noch die dazu verbundene Funktion “Validate”. In dieser Funktion werden die Daten nach den eigenen Vorstellungen geprüft, nach Abfragen die die Standardattribute wie “Required”, “MinLength”, …nicht abdecken. Dazu gehört z.B. der Vergleich zweier Datumswerte oder Strings. Dazu lassen sich dann Benutzerdefinierte Fehlermeldungen angeben und bei welchen Eingabefeldern diese Fehlermeldungen angezeigt werden sollen.

public class CustomValidationModel : IValidatableObject
{
    [Required]
    public string Name { get; set; }

    [Required]
    [DataType(DataType.Date)]
    public DateTime Birthdate { get; set; }

    [Required]
    [DataType(DataType.Date)]
    public DateTime Deathdate { get; set; }

    [Required]
    public int MinValue { get; set; }

    [Required]
    public int MaxValue { get; set; }

    public void Initilize()
    {
        Birthdate = DateTime.Now.Date;
        Deathdate = DateTime.Now.Date.AddYears(100);
    }

    /// 
    /// Die Custom Validate Methode die durch das Interface eingebunden wird.
    /// 
    public IEnumerable Validate(ValidationContext validationContext)
    {
        if (Birthdate.Date < DateTime.Now)
        {
            yield return new ValidationResult("Das Geburtsdatum muss in der Zukunft liegen", new[] { "Birthdate" });
        }

        if (MinValue  10 && MinValue > 10)
        {
            //Ausgeben der passenden Fehlermeldung und angeben bei welchen Werten die Fehlermeldung angezeigt werden soll
            yield return new ValidationResult("MaxValue und MinValue dürfen nicht größer wie 10 sein.", new[] { "MinValue", "MaxValue" });
        }

        if (Name.Trim().Length > 3 && !Name.StartsWith("Sq"))
        {
            yield return new ValidationResult("Wenn der Name länger wie 3 Zeichen ist, muss dieser mit 'Sq' beginnen.", new[] { "Name" });
        }
    }
}

Dazu muss im Controller nur noch “ModelState.IsValid” geprüft werden und schon haben wir unsere eigene Validierung eingebunden.

public ActionResult CustomValidation()
{
    CustomValidationModel model = new CustomValidationModel();
    model.Initilize();
    return View("CustomValidation", model);
}

[HttpPost]
public ActionResult CustomValidation(CustomValidationModel model)
{
    if (ModelState.IsValid)
    {
        //TODO Valides Model - Aufgaben ausführen
    }

    return View("CustomValidation", model);
}

Im View selbst können die Fehlermeldungen wie gewohnt direkt über “Html.ValidationMessageFor()” bei jedem Eingabefeld ausgegeben werden oder über das “Html.ValidationSummary()” global angezeigt werden.

</pre>
<div class="control-group">@Html.LabelFor(model => model.Name, new { @class = "control-label" })
<div class="controls">@Html.EditorFor(model => model.Name) @Html.ValidationMessageFor(model => model.Name)</div>
</div>
<pre>

 

Der Nachteil an dieser Lösung ist, das leider keine direkte Möglichkeit besteht die Serverseitige Validierung mit der Clientseitigen Validierung zu verbinden. Wer also Serverseitige und Clientseitige Validierung in MVC mit Bordmitteln verbinden möchte, der sollte sich zum ValidationAttribute und dem zugehörigen Interface IClientValidatable z.B. hier belesen.

Codeplex:

Dann unter “Source Code” –> “Browse” –> “Testprojekte” –> “Mvc4WebApiKoTb” hier findet Ihr dann die Wichtigsten Dateien im Webprojekt unter “Views/Home/CustomValidation”, “Models/HomeModels/CustomValidationModel”.

Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s