Ever since I started working with ASP.NET, back in v1.0 Beta 1, I've been creating self-validating form controls.  I've gone through a few iterations with them, but overall, the concept has stayed the same.

Here's a fun link to an archive of the old Cincinnati .NET user group.  It shows where I gave a presentation back in February of 2003 on this topic.  I was trying to remember when that was, and archive.org was able to remember for me.

On my current project, our Textbox got the most attention for validation.  We also have a SpinBox control that utilizes the Textbox and exposes all of the same properties.  I fixed a couple of bugs on a screen today related to validation on a form, and I was quickly reminded why I love self-validating controls so much.

Here's how the SpinBox is implemented in the ASPX code:

   1: <app:SpinBox Runat="server" ID="spbRatioDenominator"
   2:     FieldName="Ratio Denominator"
   3:     MaxLength="3"
   4:     MinValue="1"
   5:     MaxValue="100"
   6:     Required-Enabled="True" />

The display of this control is what you'd expect to see, a Textbox with up/down arrows next to it.  But all of the following features are implemented as well:

  • RequiredFieldValidator, which on its own renders an icon next to the control that indicates that it's required (RequiredFieldIndicator control)
  • CompareValidator, set to ensure that the data type is an integer (this can be overridden by setting the Type attribute on the control)
  • RangeValidator, set to the range of 1-100
  • The validator controls have their error message automatically formatted to reference the field name: "Ratio Denominator is required" and "Ratio Denominator must be a whole number between 1 and 100"

With ASP.NET MVC, things like this will be much more painful, and that is one of my biggest hesitations with using ASP.NET MVC.  My teams have relied on this type of productivity boost, and it would be a tough loss.  I'm very interested to see how the client-side validation problem gets solved within the MVC framework--it seems to be the biggest unknown as far as I can tell.

As an aside, this example can also serve as an example of why only having validation within the domain can fail.  If the domain only needs to know the ratio percentage, instead of the numerator and the denominator, but the UI needs to present it to the user as numerator and denominator, what do you do?

With my Extended MVP pattern, the View interface would include both the numerator and the denominator, and set up validation on both.  Then the Presenter would map that into the domain's percentage field appropriately.