Thursday, February 22, 2007
Validating inputs using Validation Application Block and XmlHttpRequest (Part I)
Enterprise Library V3 already includes Asp.Net Validation support using the Validation Application Block (VAB). You can download it and try the quickstarts from Codeplex. Here you have a Quickstart fragment showing how to use the PropertyProxyValidator to validate a TextBox control:
<asp:TextBox ID="dateOfBirthTextBox" runat="server" />
<cc1:PropertyProxyValidator ID="dateOfBirthValidator" runat="server" ControlToValidate="dateOfBirthTextBox"
OnValueConvert="dateOfBirthValidator_ValueConvert" PropertyName="DateOfBirth"
RulesetName="RuleSetA" SourceTypeName="ValidationQuickStart.BusinessEntities.Customer" />
Then the IsValid property is used when the user submits the form and all input are validated using the server side configuration (this is the attributes metadata in the domain objects or the configuration file definition). But what about the client validation that provides the rest of existent Asp.Net's validators? They use fixed or custom (provided by the user) javascript code to perform the validation and the problem is that you have to duplicate the same logic in both C# and JS languages.
I don't have the answer to how to perform a fully client validation but at least I developed a first approach to the solution using XmlHttpRequest. This solution allows you to validate each Input when it loses focus and shows the user the errors before continuing with the next input:
The solution: I extended the PropertyProxyValidator and I added to it the CustomValidator behavior. The JS function is fixed and it sends the XmlHttpRequest to the server specifying the following 3 things:
1. This is a "client side" validation.
2. The value to validate.
3. The validator id.
In the OnLoad event I check the (1) and (3) parameters. Then I execute the base EvaluateIsValid method and write the response containing the validation result and the error message to be shown. The tricky part is how to provide the GetControlValidationValue(string name) because it gets the value from the property defined in the ValidatorPropertyAttribute on the Control to validate. This property could be different in each control and should be set with the value to validate (2). So with the help of reflector and kzu we realized that in the end the TypeDescriptor features are being used to get the Property value to validate. In short we registered a TypeDescriptionProvider to return the value to validate (2) before invoking the validation and we removed this after that.
I think this was too much for this post. I will continue posting more details of the the solution in future posts so stay tuned if you are interested in!
and I will be glad to send you a fresh copy of the code (I am searching a way to upload it to somewhere). Then you will be able to use it as following (for a TextBox called "TextBox1":
ClientPropertyProxyValidator id="ClientPropertyProxyValidator1" runat="server" ControlToValidate="firstNameTextBox" PropertyName="FirstName" RulesetName="RuleSetA" SourceTypeName="ValidationQuickStart.BusinessEntities.Customer"
HTH
the rar contains two .cs files.
<< Home