EntLib Validation Application Block - Subclassing PropertyProxyValidator for ValueConvert

The Enterprise Library VAB provides the PropertyProxyValidator for ASP.NET applications so that you can attach it to a single control and it will display any validation messages for that business object property.  This automatic UI validation is great because it avoids duplicating your business layer validation logic in your UI.  Additionally, you can just use ONE validator control whereas using traditional ASP.NET validation controls you might need to attach 3-4 validation controls to a single UI element (e.g., RequireFieldValidator, RangeValidator, RegexValidator, etc.) which can clutter your aspx pages quickly.

However, one of the gotchas with working with the PropertyProxyValidator control is that, while it is quite elegant for strings, you have to do a little extra work for data types such as DateTime.  Specifically, if you are working with a DateTime, you have to attach a ValueConvert method to your PropertyProxyValidator control in which you perform the data type conversion.  The following code snippet is directly out of the VAB documentation:

  
protected void dateOfBirthValidator_ValueConvert(object sender, ValueConvertEventArgs e)  
{
        string value = e.ValueToConvert as string;
        try
        {
            e.ConvertedValue = DateTime.Parse(value, System.Globalization.CultureInfo.CurrentCulture);
        }
        catch
        {
            e.ConversionErrorMessage = "Date Of Birth is not in the correct format.";
            e.ConvertedValue = null;
        }
}

This extensibility is great but if I need to perform multiple DateTime validations like this throughout my application, I don't want to have to copy/paste this code everywhere.  Even if I encapsulate it in a static utility method, I still have to go through the pain of wiring up an event for any control where I need this just to make that 1-line call to the utility method.

So...a better approach is to simply subclass the PropertyProxyValidator control.  In the following example, I just wire up the conversion in the contructor.  This enables me to avoid having to wire up the event in the aspx code and and also enables me to avoid having to include the event in the code behind.  I just specify the DateTimePropertyProxyValidator in my aspx code the normal way:

  
<asp:TextBox id="txtDateOfBirth" runat="server" />
<vab:DateTimePropertyProxyValidator ID="dobVal" runat="server" ControlToValidate="txtDateOfBirth" PropertyName="DateOfBirth" SourceTypeName="Person"/>

The same pattern could obviously be used for other data types.  Below is the complete code for the DateTimePropertyProxyValidator:

  
public class DateTimePropertyProxyValidator : PropertyProxyValidator  
{
    public DateTimePropertyProxyValidator()
    {
        this.ValueConvert += OnValueConvert;
    }
 
    private void OnValueConvert(object sender, ValueConvertEventArgs e)
    {
        DateTime result;
 
        if (DateTime.TryParse((string)e.ValueToConvert, out result))
        {
            e.ConvertedValue = result;
        }
        else
        {
            e.ConversionErrorMessage = "Date is not in the correct format.";
            e.ConvertedValue = null;
        }
    }
}