You'll remember from my last post that I've been working on a small order-entry program in ASP.NET MVC. This is my first "from scratch" ASP.NET MVC application, so I've been learning some MVC and jQuery tricks along the way.

Here's a partial screenshot of the "new order" screen to refresh your memory:

You'll notice that each silo has a "capacity", and I wanted to be able to limit the item quantity to that value. No sense in allowing a farm to order more feed than will fit into the silo!

ASP.NET MVC's support for data annotations (in the form of attributes) to enable validation is very funky. I can mark my Quantity property up like this:

[Range(0, 99)]
public int Quantity { get; set; }

... and the generated HTML will automatically apply an error to the text input when the user types a negative value or one above 99. The markup ends up looking something like this:

<input data-val-range="Value must be between 0 and 99."
data-val-range-max="99" data-val-range-min="0" ... />

I can't remember the exact error message, but you get the idea.

This is all well and good for values that apply at compile time, but each one of my order items should have its "data-val-range-max" value set to the capacity of the silo, and I can't do that with a [Range] attribute.

I could have defined my own custom validation class and corresponding .js file to enable this sort of validation logic, but for now I have found a much easier way. In the Razor view that renders the form, I found the line the spits out the text input, and changed it to this:

So I'm still telling Razor to generate a text input box for my "Quantity" property, but I'm adding some custom attributes to the generated HTML. It looks like this now:

<input data-val="true" data-val-range="Quantity must be between 0 and 12."
data-val-range-max="12" data-val-range-min="0"... />

In this case, the silo's capacity is 12 tonne, and so the Quantity input associated with that silo has had its maximum value set to 12 too.

This gives me client-side validation of each order item's quantity without having to define my own custom validation .js code! Of course I've mirrored the logic in C#, so if the form is somehow posted with invalid data it will still get rejected. Still, this simple workaround saved me quite a lot of time, and I hope it helps you too.

The MVC3 design limitiation of only allowing model annotations to be design-time constants is constantly irritating to me, and this little hack makes decent client-side validation a hell of a lot easier.

I keep being tempted to spend some proper time rolling my own truly dynamic data validation system, but, as usual, time constraints and the need to get a product shipped override that.