Client validatie voor custom data annotations

Ik kwam in de situatie waarbij ik met stringwaarden moest controleren of deze binnen een bepaalde getal range lagen. Uiteraard is hier geen standaard MVC Data-Annotation voor, dus schreef ik hem zelf. De controle moest overigens enkel uitgevoerd worden als er een waarde is ingevuld.

Het toepassen van client side validatie van custom Data Annotations bestaat uit twee delen: het serverdeel en de client side deel.

Hier mijn implementatie van het bovenstaand beschreven probleem:

    [AttributeUsage(AttributeTargets.Property, AllowMultiple=true)]
    public class NumberStringRangeAttribute : ValidationAttribute, IClientValidatable
    {
        private int minValue;
        private int maxValue;

        public NumberStringRangeAttribute(int minValue, int maxValue)
        {
            this.minValue = minValue;
            this.maxValue = maxValue;
        }

        public override string FormatErrorMessage(string name)
        {
            return string.Format("Waarde moet tussen {0} en {1} liggen", this.minValue, this.maxValue);
        }

        public override bool IsValid(object value)
        {
            int input = 0;
            if (int.TryParse((string)value, out input))
            {
                return input >= this.minValue && input <= this.maxValue;
            }

            return true;
        }

        public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule();
            rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
            rule.ValidationParameters.Add("min", this.minValue);
            rule.ValidationParameters.Add("max", this.maxValue);
            rule.ValidationType = "numberstringrange";

            yield return rule;
        }
    }

Wat misschien meteen opvalt is de methode 'GetClientValidationRules()'. Deze moet geïmplementeerd worden omdat ik gebruik maak van de interface 'IClientValidatable'. Deze interface is nodig om client side de validatie uit te voeren.

De methode geeft een object terug die de data bevat die benodigd is in de client. De runtime serialiseert deze data in HTML-attributen op het input element. Data bevat de naam van de 'min' en 'max' properties, de naam (moet in lowercase) van de adapter ('numberstringrange') die de client nodig heeft for het deserialiseren van de data en de foutmelding die getoond moet worden als de validatie faalt.
De gegeneerde HTML ziet er dan als volgt uit als de min waarde 1900 is en de max 2200:


En dan de client side. In de client side moet er een stukje JavaScript geschreven worden:

$.validator.unobtrusive.adapters.addMinMax("numberstringrange", "min", "max", "numberstringrange");

$.validator.addMethod("numberstringrange", function (value, element, rangeParams) {

    if (value) {
        var input = parseInt(value);
        var min = parseInt(rangeParams[0]);
        var max = parseInt(rangeParams[1]);

        return input >= min && input <= max;
    }

    return true;
});

Je dient hier dus twee dingen te doen: 1) het registreren van je adapter en 2) de functie die uitgevoerd moet voor de validatie.
Een adapter haalt de data uit de data-attributen van het element en zorgt er vervolgens voor dat jQuery.validate met deze data kan omgaan. Al het harde werk wordt gedaan door de unobtrusive extensions die door MVC 3 en hoger worden aangeboden. Het enige dat moet gebeuren is de adapter vertellen dat we een nieuwe adapter willen registreren. In dit geval registreer ik een 'addMinMax' adapter. Er zijn verschillende soorten adapters die je kan registreren.
Let er bij het registreren van zo'n adapter op dat de namen overeenkomen met hoe die zijn gedefinieerd in de class op de server. In bovenstaand voorbeeld zie je dat max overeenkomt met de meegegeven waarde 2200 en min met 1900.

Meer informatie over client side validatie: http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2

bron: http://odetocode.com/blogs/scott/archive/2011/02/23/custom-data-annotation-validator-part-ii-client-code.aspx

Reacties

Populaire posts van deze blog

[SQL Server] varchar vs nvarchar

MS Sql 70-461: Chapter 5

[C#] Class serialiseren en deserialiseren