Update: I've not forgotten about this everyone, apologies for the delay. My attempt to get approval to publish failed due to vacations (mine and others) so as soon as I can I'll try again.

My blog posts on doing conditional validation in MVC have always been popular, and I’m frequently surprised by where I find that code – customers often say to me “we found some guys blog with some code to do the validation we needed” and sure enough it usually turns out to be mine!

There are two problems though – firstly, my code was always intended to be a sample to get you started, and that meant I’d not written a comprehensive set of tests. Secondly, there are all sorts of validation cases that developers need that I hadn’t covered.

So I decided to refresh the code base, both with additional validators and with a pretty decent set of tests. The first Alpha (i.e. incomplete, probably buggy, etc, etc you have been warned Smile) release of this code is attached to this blog post.

What’s in the box?

There are four main topics included in the box;

  • Conditional required validation. This is the most common requirement, and is often used for forms that have optional sections.
    • RequiredIfAttribute. This attribute says “this field is required if some other field has value X”. It is used as [RequiredIf(“OtherField”, “TargetValue”)]
    • RequiredEmptyIfAttribute. This attribute says “this field must be empty if some other field has value X”. It is used as [RequiredEmptyIf(“OtherField”, “TargetValue”)]
    • conditional-validation.js – a JavaScript file to does the above in the browser to match the server-side implementation
  • Dependency validation. Sometimes the value of one field depends on another.
    • RangeDefinedByFieldsAttribute. This states “this field must be between the values in X field and Y field”. It is used as [RangeDefinedByFields(typeof(Int32), “MinField”, “MaxField”)].
    • There is also script in conditional-validation.js to do this in the browser.
  • Validation groups. Sometimes a field is only relevant if the user clicks one of the buttons available; perhaps if they click Delete none of the edited fields must be entered.
    • RequiredForButtonAttribute. This states “the field is required if they user clicks button X”. It is used as [RequiredForButton(“ValidationGroupName”, “ButtonName”)]
    • RequiredEmptyForButtonAttribute. OK, you probably get the point now. I’ll let you infer what this does!
    • Html.SubmitForValidationGroup. To “play nice” with the RequiredForButtonAttribute and RequiredEmptyForButtonAttribute we need to ensure the buttons are created correctly, and we need a hidden field. This HtmlHelper extension handles this for us, and takes the form Html.SubmitForValidationGroup(“ValidationGroupName”, “ButtonName”)]
    • validation-groups.js – This JavaScript ensures that client-side validation groups work as well as server-side.

Note that all of these pieces work both server-side and client-side (in the browser) if you use the JavaScript included in /Mvc.ValidationToolkit.Harness/Scripts/MvcValidationToolkit/*.js.

Also, note that they all have MSTest unit tests and automated WaTiN UI tests that exercise both the JavaScript and Server implementations of each feature. I’m positive it needs more tests (for example different data types).

What do I need from you?

I must emphasise that this release is a preview. So what next? Well I want to know a few things;

  1. What do you think? Is this useful?
  2. What validators are missing?
  3. What bugs have you found?
  4. What testing priorities are there?

Please comment on this post if you’ve answers to those questions. But I also want to know where this should live and how it should move forwards. I would consider setting up a codeplex project if there were a few strong MVC & jQuery developers that wanted to add to and evolve the library. Or is this drop enough to get you started? Let me know your thoughts.

In the mean time, I may blog on using the attributes a little more if I get the chance.

Go Get It

To have a look at the code, download the attachment to this post and have a look in Readme.txt – the only thing you need to do is grab a couple of NuGet packages and everything should work. Note: if you’re running the WaTiN tests, run Visual Studio as elevated else you’ll just get timeouts.