Web Forms Data Annotation Validation – Part 2

In my last post I reviewed the new Web Forms support for server-side validation using Data Annotations, and ended with my frustration at not being able to find out how (or if) Microsoft had implemented the matching client-side validation. I promised to look at two different implementations that would provide client-side validation. This post is an overview of my first pass at a solution–using the jQuery validation plugin.

My hope was that since Microsoft had implemented client-side validation in MVC, all I would have to do was rip the code out of an MVC template and tweak it a bit to make it work in Web Forms. Sadly, it wasn’t going to be as easy as that. I brought over the appropriate JavaScript files, tried adding the web.config settings, but nothing happened. Still, at least I had the MVC JavaScript files and that meant I had the jquery.validate plugin – and since I’ve used that to get around issues in MVC validation, I could do so again for Web Forms. All I had to do was read the Data Annotations in a custom validator and inject the appropriate rules into the control to be validated. So… here goes:

The first thing I did was create a new ASP.NET server control so that the validator would be just another control in my toolbox:

New project dialog

Then I added a new class and inherited from the base validator:

inheriting base validator

That meant implementing the single method EvaluateIsValid():

overriding EvaluateIsValid

I simply return true here because the validator isn’t actually going to do any validation–it’s just going to inject the rules into the form element so that the validate plugin can do that for me. The validate plugin is able to read validation rules out of HTML class attributes. I’m going to translate DataAnnotations into the object literal arguments the plugin expects, so that when the validator reads the following Data Annotation…

Data Annotations

….it generates “{required:true, messages:{‘The from address is required’}}“inside the class attribute:

generated html

(In order for this to work, I’ll have to add the metadata plugin to my master page, as well as the validate and validate.unobtrusive plugins that I “borrowed” from the MVC template).

I’m not going to render this control itself, just inject content into the control it’s validating, so I override the PreRender event. I do the work inside the event handler (and inside a check to see if IsPostBack is false so that I’m only inject my code once). I even commented out the call to base.OnPreRender. Why bother? I’m not going to render it.

onprerender

The first task is to read the Data Annotations, so I need a reference to System.ComponentModel.DataAnnotations. Now I can use reflection to read the annotations, thus:

reflection

As you can see, I’m using TypeName, TypeAssembly and TypeProperty properties on my class to provide all the information I need to get hold of the object and its Data Annotations. These need to be provided by the UI developer, thus:

DataAnnotationValidator in aspx source

Now it’s just a question of checking the type of the validation attribute and creating the appropriate string. I did this by building two collections–one of rules, the other of messages. Here are the collections and a method used to populate them:

properties

And here is a switch inside the loop through the attributes that calls the AddValidation() method:

switching attributes

Once I have set up the rules and messages, all I need to do is create the literal and inject it into the control.

building the string

Then it’s time to test it… and nothing happens. That’s because although the validate plugin is there, there’s no call to .validate() on the page. So now I need to add in a scriptlet to make the plugin runs:

scriptlet

And then I need to register that script on the page.

registering script

Phew! Finally we’re done. All I have to do is add a reference to the library, add the DataAnnotationValidator to the toolbox (right-click and choose items, then browse to the library) and then add the appropriate validators to the page and give them the right property settings:

property settings

The DataAnnotation validator translates the rules into a form understood by the validate plugin, the validation runs and we have client-side validation:

working validation

Obviously, there are a lot of things that can be improved in this version. It doesn’t cover all the possible Data Annotations. It doesn’t allow for missing error messages. It only validates TextBox controls. I could improve it, but I’m not going to: I decided I didn’t like the dependency on the metadata plugin, and I hated having to inject JavaScript into the page. So I decided to go back to square one, forget about bringing in any scripts from the MVC version and work with the unobtrusive validators that come with the Web Forms template instead. And that’s what I’m going to cover in my next post.

(If you’re interested in the full code for this version of the DataAnnotation validator, it’s online here: DataAnnotation.txt.)

Kevin Rattan

For related information, check out these courses from Learning Tree:

Building Web Applications with ASP.NET and Ajax

jQuery: A Comprehensive Hands-On Introduction

Type to search blog.learningtree.com

Do you mean "" ?

Sorry, no results were found for your query.

Please check your spelling and try your search again.