c# - Best approach for Client-side validation for each custom rule in FluentValidation -


i using fluentvalidation in asp.net mvc 4 application. have known rules automatically generating attributes jquery validation library. , script library has known must check example in case of data-rule-required, data-rule-range , on.

i know there functions in fluentvalidation, these not include client-side. example: .equal(true). have checked @darindimitrov answer here , implemented without problem.

but, don't want create new class inherited fluentvalidationpropertyvalidator. , must add provider in global.asax:

provider.add(typeof(equalvalidator), (metadata, context, description, validator) => new equaltovalueclientrule(metadata, context, description, validator)); 

in case equalvalidator implemented in fluentvalidation. but, if have created validator when keyword. example, have:

this.rulefor(phone => phone.digits)     .length(7)         .when(phone => phone.prefixid == 2)         .withmessage("numbers in 2nd city must contain 7 characters");  this.rulefor(phone => phone.digits)     .length(7)         .when(phone => phone.prefixid > 64)         .withmessage("mobile number must contain 7 characters");  this.rulefor(phone => phone.digits)     .length(5)         .when(phone => phone.prefixid != 2)         .withmessage("numbers in other cities must contain 5 characters") 

of course, can check jquery/javascript without problem. but, approach not good. , in other cases have write code generating custom attributes in client side , add new function adapter. or, use jquery/javascript? or other thing? may can add javascript function name fluentvalidationpropertyvalidator?

what recommend me?

i have thought lot , find best way create new validator inherits propertyvalidator , implements iclientvalidatable interface. result, contain server-side validation , generate unobtrusive attributes wish. must need register new validator in unobtrusive library.

for example, validator rules in question be:

public class mustfittophoneprefix<tmodel, tproperty> : propertyvalidator, iclientvalidatable     {         private string dependencyelement;          public mustfittophoneprefix(expression<func<tmodel, tproperty>> expression)             : base("format wrong")         {             dependencyelement = (expression.body memberexpression).member.name;         }          // server side validation         protected override bool isvalid(propertyvalidatorcontext context)         {             // instance of class contains property must validated              var phone = context.parentcontext.instancetovalidate phonedetail;              ...             // custom logic             ...              // valid             return true;         }          // generate jquery unobtrusive attributes         public ienumerable<modelclientvalidationrule> getclientvalidationrules(modelmetadata metadata, controllercontext context)         {             var rule = new modelclientvalidationrule             {                 errormessage = this.errormessagesource.getstring(), // default error message                 validationtype = "fittoprefix" // name of validatoin used inside unobtrusive library             };              rule.validationparameters["prefixelement"] = dependencyelement; // html element includes prefix information             yield return rule;         } 

and can register our client-side validator:

// check if phone number fits phone prefix $.validator.addmethod('fittoprefix', function (value, element, params) {     var parent = getparentpropertyname(element);     var prefixid = $("#{0}_{1}".format(parent, params.prefixelement)).val();     var digitslength = $(element).val().length;      ...     // custom logic     ...      return true; });  // registration - check if phone number fits phone prefix $.validator.unobtrusive.adapters.add('fittoprefix', ['prefixelement'], function (options) {     options.rules['fittoprefix'] = options.params;     if (options.message != null) {         options.messages['fittoprefix'] = options.message;     } }); 

and @ last, can set our validator:

   this.rulefor(m => m.digits)        .setvalidator(new mustfittophoneprefix<phonedetail, int>(m => m.prefixid));