Model-based Client-side Validation for ASP.NET MVC
ASP.NET, MVC, Usability April 30th, 2008For quite a while, I was unsure how to go about doing validation in ASP.NET MVC. By default, it’s incompatible with the ASP.NET <asp:XyzValidator> server controls, so this gives us an opportunity to come up with something newer and better.
There have been a couple of great efforts from the community, including Juergen Baeurle’s MVC Validator Toolkit, and Matt Hawley’s MVC UI Validation Framework (now part of MVC Contrib). I wasn’t really satisfied with either, because they take validation out of the domain model and into the application’s UI (no offense guys, what you’ve done is cool).
So, check out my first ever screencast - 6 thrilling minutes of non-stop coding action, in which you get to add both server-side and breathtakingly fit client-side validation to an ASP.NET MVC application, while keeping all the validation rules right in the domain model. Whoo!
Oh noes! Either your feed reader has removed the screencast, or you haven’t enabled Javascript and Flash. You’re missing out!
For those of you that don’t have time for screencasts (like me, normally), here’s how to get the client-side validation goodness in your ASP.NET MVC application. I’m using Castle Validator for the server-side bits, and Live Validation for the client-side bits, fused into one terrifying alien beast hell-bent on ultimate data purity.
Instructions
1. Download and reference MvcValidator.dll and Castle.Components.Validator.dll (from the Castle project). In your master page, add a reference to the Live Validation script (preferably a local copy of it):
<script src="http://www.livevalidation.com/javascripts/src/1.3/livevalidation_standalone.compressed.js"></script>
2. Add validation attributes to your model object.
public class Person { [ValidateNonEmpty("Please enter a name")] public string Name { get; set; } [ValidateNonEmpty("Please enter an email address")] [ValidateEmail] public string Email { get; set; } [ValidateNonEmpty("Please enter an age")] [ValidateInteger] public int? Age { get; set; } }
3. Drop an Html.ClientSideValidation into your view:
<% using(Html.Form("Home", "SubmitPerson", FormMethod.Post)) { %> <p>Name: <%= Html.TextBox("MyPrefix.Name", ViewData.Name) %></p> <p>Email: <%= Html.TextBox("MyPrefix.Email", ViewData.Email)%></p> <p>Age: <%= Html.TextBox("MyPrefix.Age", ViewData.Age)%></p> <%= Html.ClientSideValidation(ViewData, s => "MyPrefix." + s) %> <%= Html.SubmitButton() %> <% } %>
4. Strut, pose, be smug. You’re done!

Optional steps:
5. Add server-side validation keyed off the same validation attributes, using Castle Validator’s ValidatorRunner (the screencast shows this in action before the client-side validation).
6. Add CSS rules to get the red/green border effect as shown in the screenshot.
Downloads
Thoughts
I’d really love to see something along these lines baked into the official MVC framework, perhaps following Castle’s example of having a pluggable system for emitting Javascript for particular validation checks, so folks could integrate it with client-side validation libraries of their choice. (In my version, I’ve just hard-coded it to work with Live Validator.)

April 30th, 2008 at 2:39 pm
Validation attributes seem to be coming in System.ComponentModel.DataAnnotations from the scaffolding work in ASP.NET Dynamic Data. I hope that work from Microsoft develops quickly. I assume they are waiting for the updated previews of MVC before a newer version of MVC Dynamic Data is done, which should hint at the direction for validation.
Yes, I do think this code looks far simpler to integrate and more elegant than the current code in MVCContrib for validation. Many thanks for the code.
April 30th, 2008 at 2:42 pm
Thanks. This is great.
April 30th, 2008 at 4:38 pm
[…] Model-based Client-side Validation for ASP.NET MVC […]
May 1st, 2008 at 7:19 am
[…] Model-based Client-side Validation for ASP.NET MVC - Steve Sanderson looks at validation in ASP.NET MVC applications, with the validation being handled in the model classes rather than the View or controller as often happens […]
May 1st, 2008 at 8:39 am
Brilliant! What about validating the model on the serverside with the same attributes?
May 1st, 2008 at 11:57 am
Hey Scott,
It’s quite easy to do the same validation on the server too. I didn’t make a big point of it, but it’s shown in the middle of the screencast somewhere! Also, the demo project does this.
May 1st, 2008 at 3:27 pm
Steve, thank you for posting this — its exactly what I was trying to do (perform validation with out having code in the UI)
May 1st, 2008 at 4:35 pm
Fantastic! Now to make those attributes work with WinForms as well.
May 1st, 2008 at 5:25 pm
Very nice. Your solution is way more elegant than the stuff I was coming up with. Thanks for the great post!
May 1st, 2008 at 5:31 pm
Very Coooooool Post!!!
May 2nd, 2008 at 10:52 am
This is a nice way of dealing with validation.
However, in this sample the error message is hard coded in the attribute. How would you go about internationalizing this if it became a requirement?
May 2nd, 2008 at 12:20 pm
Anastasiosyal - that’s definitely a good point, and there are also other cases where you’d want to vary the message. (e.g. “Please enter a name” OR “Please enter your name” depending on context).
A couple of things to consider:
[1] Instead of having fixed strings in the validation attributes, you could have references to resource file entries. It might be cleaner if you add explicit support for that to Castle Validator.
[2] You could add placeholders into the error message strings, e.g. “Please enter {owner} name”, then add means of passing parameters to Html.ClientScript, e.g. Html.ClientScript(ViewData, new { owner = “your” })
May 2nd, 2008 at 12:48 pm
I’d really like to be able to use this as it’s a lot cleaner than what I’ve been doing. The problem I see with the attribute based validation is when used with code generators, i.e. subsonic/linq2sql etc. As far as I know there isn’t any way to decorate properties with partial classes, although I do remember seeing something about this for dynamic data. Any thoughts on this?
May 2nd, 2008 at 3:46 pm
How to decorate your model with attributes if this model has been generated by the VS Linq to Sql designer ?
May 2nd, 2008 at 5:18 pm
Justin and Nicolas,
That’s a good question, and I hadn’t thought of that previously. When I use LINQ to SQL, I prefer to write the class definition and mapping manually (not using the code generator), so of course there’s no problem.
If you really do want to use the codegen, I’d say you have two options:
[1] Add ICustomTypeDescriptor on to the partial class, then implement GetProperties() to return the properties with validation attributes added. This will work because MvcValidation.dll inspects your model object using System.ComponentModel instead of raw reflection.
[2] Create some other interface, ICanHasValidationPlz, and attach it to the partial classes. Then change the ClientSideValidation() method to check for your ICanHasValidationPlz interface, calling some special “GetValidationAttributes(string propertyName)” method on that interface where implemented (falling back on ComponentModel if not).
May 2nd, 2008 at 7:32 pm
Thank you Steve. These are 2 nice possibilities.
May 4th, 2008 at 5:02 pm
I’m supprised that the “buddy class” approach for defining (validation) metadata for generated classes from Dynamic Data isn’t getting more coverage in blogs. As it really could become a standard approach.
http://blogs.msdn.com/davidebb/archive/2008/03/06/dynamic-data-at-mix-and-upcoming-changes.aspx
May 5th, 2008 at 8:29 am
Good point Andy. That would be an effective workaround here.
May 5th, 2008 at 8:23 pm
[…] Model-based Client-side Validation for ASP.NET MVC […]
May 5th, 2008 at 8:24 pm
[…] Model-based Client-side Validation for ASP.NET MVC […]
May 6th, 2008 at 5:27 am
You have just plugged LiveValidation JS library support and used Castle validators.
It would probably be more preferable if you’d use Castle’s java-script support for that.
Not sure what about ASP.NET MVC.
Anyway, thanks for sharing you work.
May 6th, 2008 at 8:51 am
Hi Dmitriy -
Yes, I did use Live Validation and Castle Validator, and in fact I said so in the blog post, and in the screencast! It’s not a secret…
The ASP.NET MVC element is mainly demonstrating how to use this style of validation neatly, since up until now I hadn’t seen anyone else doing so with this platform. I’ve supplied an HTML helper method that, I hope, makes it much easier.
> It would probably be more preferable if you’d use Castle’s java-script support
I did try that at first, but it wasn’t as streamlined as I wanted (it requires you to inject code both at the top and bottom of the <form>), and I’m aiming for maximum slickness here. Plus, for this task I prefer Live Validation above jQuery and fValidate, so I needed to write a custom provider anyway.
May 9th, 2008 at 3:22 pm
Very very cool. I’m going to try this as soon as I get back into work.
May 9th, 2008 at 8:04 pm
[…] Permanent Link to Model-based Client-side Validation for ASP.NET MVC Possibly related posts: (automatically generated)Validator Toolkit for ASP.NET MVCASP.NET MVC Request LifecycleASP.NET MVC Framework? Yeah baby! […]
May 19th, 2008 at 7:05 pm
Steve, could you provide one example implementing the solution that you proposed: “Add ICustomTypeDescriptor on to the partial class, then implement GetProperties() to return the properties with validation attributes added. ”
Thanks
June 2nd, 2008 at 10:27 pm
I think this is a nice add on to ASP.NET MVC. I have one question though, and it’s something that has always bothered me about using domain objects to back pages directly in Java and now in C#.
As both languages are statically typed we can’t rely on them to take any form based content and validate server side. For example, using server side validation only, putting “woo” into the age field in your example gives me a “FormatException: Input string was not in a correct format.”.
So to my question, is there anything that can be done to keep the domian strongly typed, i.e. don’t put a ’string ageAsString’ property on it, and still do all the validation on the domain object using the Castle attributes? Sadly, I expect the answer is no.
June 3rd, 2008 at 5:20 pm
Hi Chris
You are right about the FormatException. It happens because, in the demo code, I call BindingHelperExtensions.UpdateFrom(…) to populate the model object, but don’t make any effort to catch PopulateTypeException that it (supposedly) throws in this case, telling you which field it was unable to populate.
If you’re aiming for production-grade code, and aren’t happy to rely on client-side validation, you need to catch these and respond appropriately. This is a bit awkward because there isn’t an obvious way of mapping the PopulateTypeExceptions to your own friendly error messages.
Also note that in CTP3, BindingHelperExtensions.UpdateFrom(…) seems to have a bug in that it doesn’t throw the PopulateTypeExceptions at all. It may just be my mistake though - I haven’t properly confirmed this.
June 9th, 2008 at 10:08 am
I sm downloading the source code but have a error
The name ‘RenderView’ does not exist in the current context
June 9th, 2008 at 2:15 pm
Hi Rajendra - are you using the new CTP3? If so, that was released after I wrote this blog post, and it changes the API slightly. You need to replace RenderView() with View(). I’m not going to update this blog post for CTP3, because the current indication is that fairly soon the MVC framework itself will have a similar (presumably better) validation feature built-in.
June 10th, 2008 at 11:55 am
Thnks Steve
I have implemented all but I didnt see Red Green border to textbox for validation..
I copied css also
June 13th, 2008 at 9:03 am
[…] Lack of validation (alternative solution) […]
June 13th, 2008 at 1:54 pm
I think this is a nice add on to ASP.NET MVC. but I have a prblem regarding I want to do many validations on a single textbox How to do that
June 13th, 2008 at 2:54 pm
Allen, you can add multiple validation attributes to each model field. For example, as shown in step 2 above,
[ValidateNonEmpty(”Please enter an age”)] [ValidateInteger]
public int? Age { get; set; }
June 14th, 2008 at 5:43 am
thats working,
dynamically add ValidateRegExp to a single textbox
June 23rd, 2008 at 11:52 am
Great, you really understand the problem domain. Validation rules on the model, remembering the entered data, easy insertion of client side validation framework.
You should still work on this some more, because it’s just so nice.
July 3rd, 2008 at 12:21 pm
Hi Steve,
Excellent post. I’m investigating MVC for a new project and validation has been one of my major concerns, but this is really nice.
I do have a question: Can you explain where Html.ClientSideValidation is coming from? That is, where is it declared? Is this part of the Castle dll? Or something else? I’d like to understand exactly, in more detail, how the Live Validation script is getting wired to the form.
Thanks so much,
Adam
July 3rd, 2008 at 1:33 pm
Hi Adam
Html.ClientSideValidation() is defined in the MvcValidation.dll offered as a download with the post. This generates the appropriate JavaScript to get Live Validation running.
Steve
July 3rd, 2008 at 9:52 pm
Hi Steve,
I downloaded the source code, opened the solution and run the web demo and everything works fine.
But, when I compile the MvcValidation project and use the dll generated in other web project I get an error in the Html.ClientSideValidation(ViewData) line. The error is: “ClientSideValidation’ is not a member of System.Web.Mvc.HtmlHelper”
If I download the dll directly from your link, I put in the other same web project everything works correctly. What I missing when compile the MvcValidation project?
TIA