WCSF Validation Tweaks

WCSF Validation Tweaks

We recently implemented the Validation Bundle from P&P. The Bundle consists of the VAB PropertyProxyValidator from EntLib, as well as a custom ASP.NET AJAX control extender which provides the client callback support.

For the most part the Bundle rocks, but there are a few things which didn’t meet our needs:

The default PropertyProxyValidator inherits from System.Web.UI.WebControls.BaseValidator, like the other Asp.Net validators. This makes it great for mixing all types of standard Validators (Like Regex or RequiredField), but has a major drawback for Client side validation because it validates on every PostBack (full) as well as Callback (partial).

On a full postback, such as a form submit, the ServerSideValidationExtender issues a Callback request to the Validator

Even if the value had not changed, validation still occurs.

A simple scenario

We have an Organization with two fields, Name & Code

Lets look at the validation events:

Enter Name ‘Bob’s Plumbing’, Press Tab (or click off)

Callback: Validation occurs for Name

Enter Code ‘BPL’, Press Tab (or click off)

Callback: Validation occurs for Code

Click Save

Callback: Validation occurs for Name

Callback: Validation occurs for Code

Postback (full): Validation Occurs for Name & Code

So we have validated each property 3 times. This might be OK we were just parsing for special characters, but in our case we also want to call a service and see if these values already exist in our system: 3x is too expensive.

Aside from being expensive, this is a unique type of validation where we want to check if a condition isn’t true (Org Name doesn’t exist) vs. is true. (an valid email address or a valid state)

This makes point #3 above especially troubling for our scenario, because if we want to edit this Organization in the future, any time we change a value, all the rest of the validators will fire and come back invalid as they already exist.

Example updating just the Org Code, which causes the Name to validate:

The Solution

Kill the full postback validation with OnCallBackPropertyProxyValidator

Modify ServerSideValidationExtender to *only* validate if the value has changed

OnCallBackPropertyProxyValidator

OnCallBackPropertyProxyValidator is a pretty quick fix. We will just inherit the ProperyProxyValidator and kick out of the EvaluateIsValid method if its not a CallBack.

1:/// <summary>

2:/// Class which only performs validation when page is in a callback state

7:/// If Page.IsCallBack, determines whether the content in the input control is valid.

8:/// </summary>

9:/// <returns><see langword="true"/> if the control is valid; otherwise, <see langword="false"/>.</returns>

10:protectedoverridebool EvaluateIsValid()

11: {

12:if (!this.Page.IsCallback)

13: {

14:this.ErrorMessage = "";

15:returntrue;

16: }

17:else

18: {

19:returnbase.EvaluateIsValid();

20: }

21: }

22: }

ServerSideValidation

Well add the ‘only-validate-if-value-changed’ functionality by fetching the current text value from the control to be validated, storing the property in JSON, and then evaluating if the value has changed before requesting validation from the server.

And that’s it. What we end up with is client side validation which only occurs when the value is changed on the client, through a callback, and no where else. All other validation works in tandem as expected, such as the standard ASP.NET validators, PropertyProxyValidator, or a custom validator which performs VAB self validation.

Though the Bundle didn’t do everything we were looking for right out of the box, it was pretty easy to get in there and make work exactly how we wanted. Hats off to P&P for some great guidance.

The source code is here. Its just the files, not a complete working solution, but if you download the WCSF source/ Validation Bundle you should be able to plug it in fairly easily.