asp.net mvc - Passing the ErrorMessage for clientside validation -
since there no way validate property (with unobtrusive clientside validation) using multiple regex patterns (because validation type has unique) decided extend fluentvalidation can following.
rulefor(x => x.name).notempty().withmessage("name required") .length(3, 20).withmessage("name must contain between 3 , 20 characters") .match(@"^[a-z]").withmessage("name has start uppercase letter") .match(@"^[a-za-z0-9_\-\.]*$").withmessage("name can contain: a-z 0-9 _ - .") .match(@"[a-z0-9]$").withmessage("name has end lowercase letter or digit") .notmatch(@"[_\-\.]{2,}").withmessage("name cannot contain consecutive non-alphanumeric characters");
last thing need figure out how pass errormessage set using withmessage() via getclientvalidationrules() ends in "data-val-customregex[somefancystringheretomakeitunique]" attribute on input element.
public ienumerable<modelclientvalidationrule> getclientvalidationrules(modelmetadata metadata, controllercontext context) { var rule = new modelclientvalidationrule(); rule.errormessage = [insert errormessage here]; rule.validationtype = "customregex" + stringfunctions.randomletters(6); rule.validationparameters.add("pattern", pattern); yield return rule; }
i've been looking @ fluentvalidation sourcecode, couldn't figure out. got ideas?
i've been discussing how jeremy skinner (the creator of fluent validation) at
http://fluentvalidation.codeplex.com/discussions/253505
he kind enough write complete example.
update
here code came with:
first extensions, both match , notmatch.
public static class extensions { public static irulebuilderoptions<t, string> match<t>(this irulebuilder<t, string> rulebuilder, string expression) { return rulebuilder.setvalidator(new matchvalidator(expression)); } public static irulebuilderoptions<t, string> notmatch<t>(this irulebuilder<t, string> rulebuilder, string expression) { return rulebuilder.setvalidator(new matchvalidator(expression, false)); } }
the used interface validator
public interface imatchvalidator : ipropertyvalidator { string expression { get; } bool mustmatch { get; } }
the actual validator:
public class matchvalidator : propertyvalidator, imatchvalidator { string expression; bool mustmatch; public matchvalidator(string expression, bool mustmatch = true) : base(string.format("the value {0} match given expression, while {1}.", mustmatch ? "did not" : "did", mustmatch ? "should" : "should not")) { this.expression = expression; this.mustmatch = mustmatch; } protected override bool isvalid(propertyvalidatorcontext context) { return context.propertyvalue == null || context.propertyvalue.tostring() == string.empty || regex.ismatch(context.propertyvalue.tostring(), expression) == mustmatch; } public string expression { { return expression; } } public bool mustmatch { { return mustmatch; } } }
the adaptor register validator:
public class matchvalidatoradaptor : fluentvalidationpropertyvalidator { public matchvalidatoradaptor(modelmetadata metadata, controllercontext controllercontext, propertyrule rule, ipropertyvalidator validator) : base(metadata, controllercontext, rule, validator) { } imatchvalidator matchvalidator { { return (imatchvalidator)validator; } } public override ienumerable<modelclientvalidationrule> getclientvalidationrules() { var formatter = new messageformatter().appendpropertyname(rule.propertydescription); string errormessage = formatter.buildmessage(validator.errormessagesource.getstring()); yield return new modelclientvalidationmatchrule(matchvalidator.expression, matchvalidator.mustmatch, errormessage); } }
and magic happens:
public class modelclientvalidationmatchrule : modelclientvalidationrule { public modelclientvalidationmatchrule(string expression, bool mustmatch, string errormessage) { if (mustmatch) base.validationtype = "match"; else base.validationtype = "notmatch"; base.validationtype += stringfunctions.randomletters(6); base.errormessage = errormessage; base.validationparameters.add("expression", expression); } }
update 2:
javascript wireup jquery.validator:
(function ($) { function attachmatchvalidator(name, mustmatch) { $.validator.addmethod(name, function (val, element, expression) { var rg = new regexp(expression, "gi"); return (rg.test(val) == mustmatch); }); $.validator.unobtrusive.adapters.addsingleval(name, "expression"); } $("input[type=text]").each(function () { $.each(this.attributes, function (i, attribute) { if (attribute.name.length == 20 && attribute.name.substring(0, 14) == "data-val-match") attachmatchvalidator(attribute.name.substring(9, 20), true); if (attribute.name.length == 23 && attribute.name.substring(0, 17) == "data-val-notmatch") attachmatchvalidator(attribute.name.substring(9, 23), false); }); }); } (jquery));
Comments
Post a Comment