asp.net mvc client side validation -


i've been tinkering client side validation features in asp.net mvc after reading scottgu's blog post on subject. it's pretty easy use system.componentmodel.dataannotations attributes this:

    [required(errormessage = "you must specify reason")]     public string reasontext { get; set; } 

... happens if need little more complex. if have address class postalcode , countrycode field. want validate postal code against different regex each country. [0-9]{5} works usa, need different 1 canada.

i got around rolling own validationservice class takes modelstate property of controller , validates accordingly. works great on server side doesn't work fancy new client side validation.

in webforms use javascript-emitting controls requiredfieldvalidator or comparevalidator easy stuff , use customvalidator complex rules. way have validation logic in 1 place, , benefit of rapid javascript validation simple stuff (90% of time) while still security of server side validation backstop.

what equivalent approach in mvc?

edit: assumes using mvc 3. unfortunately code in vb.net since that's have use @ work.

in order make work nicely new unobtrusive validation there few things have do. powered through them couple of weeks ago.

first, create custom attribute class inherits validationattribute. simple requiredif attribute class below:

imports system.componentmodel imports system.componentmodel.dataannotations  <attributeusage(attributetargets.field or attributetargets.property, allowmultiple:=false, inherited:=false)> _ public notinheritable class requiredifattribute     inherits validationattribute      private const    _defaulterrormessage string = "'{0}' required."     private readonly _dependentproperty   string     private readonly _targetvalues        object()      public sub new(dependentproperty string, targetvalues object())          mybase.new(_defaulterrormessage)          _dependentproperty = dependentproperty         _targetvalues      = targetvalues      end sub      public sub new(dependentproperty string, targetvalues object(), errormessage string)          mybase.new(errormessage)          _dependentproperty = dependentproperty         _targetvalues      = targetvalues      end sub      public readonly property dependentproperty() string                     return _dependentproperty         end     end property      public readonly property targetvalues() object()                     return _targetvalues         end     end property      public overrides function formaterrormessage(name string) string          return string.format(globalization.cultureinfo.currentuiculture, errormessagestring, name)      end function      protected overrides function isvalid(value object, context validationcontext) validationresult          ' find other property need compare using reflection         dim propertyvalue = context.objecttype.getproperty(dependentproperty).getvalue(context.objectinstance, nothing).tostring()          dim match = targetvalues.singleordefault(function(t) t.tostring().tolower() = propertyvalue.tolower())          if match isnot nothing andalso value nothing             return new validationresult(formaterrormessage(context.displayname))         end if          return nothing      end function  end class 

next, need implement validator class. class responsible letting mvc know client validation rules required unobtrusive validation library work.

public class requiredifvalidator     inherits dataannotationsmodelvalidator(of requiredifattribute)      public sub new(metadata modelmetadata, context controllercontext, attribute requiredifattribute)          mybase.new(metadata, context, attribute)      end sub      public overrides function getclientvalidationrules() ienumerable(of modelclientvalidationrule)          dim rule new modelclientvalidationrule() {.errormessage = errormessage,                                                           .validationtype = "requiredif"}          rule.validationparameters("dependentproperty") = attribute.dependentproperty.replace("."c, htmlhelper.idattributedotreplacement)          dim first       boolean = true         dim arraystring new stringbuilder()          each param in attribute.targetvalues             if first                 first = false             else                 arraystring.append(",")             end if             arraystring.append(param.tostring())         next          rule.validationparameters("targetvalues") = arraystring.tostring()          return new modelclientvalidationrule() {rule}      end function  end class 

now can register in application start method of global.asax:

dataannotationsmodelvalidatorprovider.registeradapter(gettype(requiredifattribute), gettype(requiredifvalidator)) 

this gets 90% of way there. need tell jquery validate , ms's unobtrusive validation layer how read new attributes:

/// <reference path="jquery-1.4.1-vsdoc.js" /> /// <reference path="jquery.validate-vsdoc.js" />  /* javascript custom unobtrusive validation    ==================================================== */  (function ($) {      // adds custom "requiredif" validator jquery validate plugin     $.validator.addmethod('requiredif',                           function (value, element, params) {                                // "value" variable must not empty if dependent value matches                               // 1 of target values                               var dependentval = $('#' + params['dependentproperty']).val().trim().tolowercase();                               var targetvalues = params['targetvalues'].split(',');                                // loop through target values                               (i = 0; < targetvalues.length; i++) {                                   if (dependentval == targetvalues[i].tolowercase()) {                                       return $.trim(value).length > 0;                                   }                               }                                return true;                           },                           'not used');      // tells ms unobtrusive validation layer how read     // html 5 attributes output custom "requiredif" validator     $.validator.unobtrusive.adapters.add('requiredif', ['dependentproperty', 'targetvalues'], function (options) {          options.rules['requiredif'] = options.params;         if (options.message) {             options.messages['requiredif'] = options.message;         }      });  } (jquery)); 

hope helps, real pain working.


Comments

Popular posts from this blog

python - Scipy curvefit RuntimeError:Optimal parameters not found: Number of calls to function has reached maxfev = 1000 -

c# - How to add a new treeview at the selected node? -

java - netbeans "Please wait - classpath scanning in progress..." -