ASP.NET MVC: Adding client-side validation to ValidatePasswordLengthAttribute in ASP.NET MVC 3 Preview 1
This is the second post in what has become a mini-series:
- ASP.NET MVC: Adding client-side validation to ValidatePasswordLengthAttribute
- ASP.NET MVC: Adding client-side validation to ValidatePasswordLengthAttribute in ASP.NET MVC 3 Preview 1 (this post!)
- ASP.NET MVC: Adding client-side validation to PropertiesMustMatchAttribute
- ASP.NET MVC: Adding client-side validation to PropertiesMustMatchAttribute in ASP.NET MVC 3 Preview 1
- ASP.NET MVC: ValidatePasswordLength and PropertiesMustMatch in ASP.NET MVC 3 RC2
In the previous post we saw how we can add client-side validation to the ValidatePasswordLengthAttribute that is supplied in the default project template.
To recap, the required steps were:
- The client-side validation code
- ModelClientValidationRules that specify how to hook up to the client-side validation
- An adapter class that ASP.NET MVC uses to translate our validation attribute into ModelClientValidationRules and register this with the DataAnnotationsModelValidationProvider
To me, the first couple of steps seemed fine, but the final step seemed to be a slight over-complication. The need to register the adapter also hindered reuse of validation across projects (nothing major, but a mild annoyance). Fortunately this area has received some attention in Preview 1 of ASP.NET MVC 3.
There is now an IClientValidatable interface that the attribute itself can implement. The DataAnnotationsModelValidationProvider checks for this and if present uses it to hook up the client validation. This means that our new steps are:
- The client-side validation code!
- ModelClientValidationRules that specify how to hook up to the client-side validation
- Implement IClientValidatable on our attribute
I’ll skip the first two steps as they’re the same as in the previous post. The final step requires us to add the IClientValidatable implementation to ValidatePasswordLengthAttribute. To do this we just need to add a GetClientValidationRules method that is pretty much the same as the implementation in our adapter class from the previous post:
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new ModelClientPasswordLengthValidationRule(FormatErrorMessage(metadata.DisplayName), _minCharacters);
}
With this in place we don’t need the adapter class (which simplifies the code) and we don’t need to register anything with the DataAnnotationModelValidatorProvider as it automatically checks whether the attribute implements IClientValidatable (which improves reuse).
All in all I think that this is a rather nice simplification of the validation system for ASP.NET MVC 3!
More on MVC 3 Preview 1:
- ScottGu’s introductory post: https://weblogs.asp.net/scottgu/archive/2010/07/27/introducing-asp-net-mvc-3-preview-1.aspx
- Phil Haack’s introductory post: https://haacked.com/archive/2010/07/27/aspnetmvc3-preview1-released.aspx
- Brad Wilson’s post series on Service Location in MVC 3: https://bradwilson.typepad.com/blog/2010/07/service-location-pt1-introduction.html
Comments
Anonymous
January 19, 2011
How do you implement client-side validation when using IValidatableObject instead of validation attributes?Anonymous
January 25, 2011
Hi Flower Guy, I don't believe you can hook up client validation with IValidatableObject Stuart