Since there is no way to validate a property (with unobtrusive clientside validation) using multiple regex patterns (because validation type has to be unique) i decided to extend FluentValidation so i can do the following.
RuleFor(x => x.Name).NotEmpty().WithMessage("Name is required")
.Length(3, 20).WithMessage("Name must contain between 3 and 20 characters")
.Match(@"^[A-Z]").WithMessage("Name has to start with an uppercase letter")
.Match(@"^[a-zA-Z0-9_\-\.]*$").WithMessage("Name can only contain: a-z 0-9 _ - .")
.Match(@"[a-z0-9]$").WithMessage("Name has to end with a lowercase letter or digit")
.NotMatch(@"[_\-\.]{2,}").WithMessage("Name cannot contain consecutive non-alphanumeric characters");
The last thing i need to figure out is how to pass the errormessage which is set using WithMessage()
via GetClientValidationRules()
so it ends up in the "data-val-customregex[SOMEFANCYSTRINGHERETOMAKEITUNIQUE]" attribute on the 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 at the FluentValidation sourcecode, but couldn't figure it out. Anyone got any ideas?
I've been discussing how to do this with Jeremy Skinner (the creator of Fluent Validation) at
http://fluentvalidation.codeplex.com/discussions/253505
He was kind enough to write a complete example.
Update
Here is the code we came up with:
First the extensions, for both Match and NotMatch.
The used interface for the validator
The actual validator:
The adaptor to register the validator:
And finally where the magic happens:
Update 2:
Javascript to wireup jQuery.validator:
A little off topic, but maybe helpful. Regex are pretty powerful, have you considered combining all the rules in one regex? I think that's why the attributes providing regex validation usually don't allow multiple instances per property.
So for your example, your regex would be:
And a handy place to test it: http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx