5,550,131 members and growing! (18,926 online)
Email Password   helpLost your password?
Web Development » Validation » Validation Controls     Intermediate License: The Code Project Open License (CPOL)

Client side validation running server side code

By Artiom Chilaru

The article explains how to easily run server-side validation methods on the client-side
C# (C# 2.0, C# 3.0, C#), ASP.NET

Posted: 29 Jun 2008
Updated: 26 Jul 2008
Views: 9,089
Bookmarked: 31 times
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
9 votes for this Article.
Popularity: 3.96 Rating: 4.15 out of 5
1 vote, 11.1%
1
0 votes, 0.0%
2
0 votes, 0.0%
3
4 votes, 44.4%
4
4 votes, 44.4%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Introduction

Form validation is one of the basics of .NET web development. ASP.NET comes with several default validators, and a CustomValidator for any other kinds of validation.

As you know the CustomValidator allows us to implement server-side and client-side validation, which will make it functional, and user-friendly at the same time. But some validation cannot be simply done on the client side, and can only be implemented on the server side. For example checking if an e-mail exists in the database during a user registration.

I decided to find a way around it, and make my validation more friendly and responsive.

Background

After some research, and a bit of Googling, I realised that there aren't many simple solutions out there. The basic idea looked like this: use a custom validator, and make it's client-side validation function run a .NET WebMethod in code behind. Sounds simple in theory, but the ones who tried to implement this faced an obstacle: running web methods from javascript is done asynchronously. Ouch...

There were several solutions/tests I found online:

  • Run the async WebMethod, and cycle in a loop until you get your result. The drawback - 100% CPU usage until we get the result.
  • Rewrite the XMLHttpRequest method to run synchronously. The drawback - the code is quite massive, and we're looking for a simple solution.

I have found another article, that also did the job. The author ran the validation asynchronously, and provided the OnSuccess method. When the validation result came, he refreshed the validator. The solution sounds very good, but it was still too bulky, and provided a number of things that I thought to be unnecesary. But that was a good start, so I decided to implement a similar solution, but quite more elegant and simple.

Implementation

The idea is simple. We create a custom validator, and in the client validation run the WebMethod in the code behind, providing the OnSuccess method. When the result comes in, the OnSuccess method will set the validation result in the validator's issuccess property, and refresh the validator.

Thankfully, the .NET framework has a javascript method to refresh a validator: ValidatorUpdateDisplay() that receives a validator id as a parameter. For each validator, we get 2 js methods: A client validation, and a OnSuccess method. The reason for this is that each OnSuccess method will have to update a different validator.

Finally, when everything was finished, I wrapped it up in a validator control. The control derives from CustomValidator, so it has all it's functionality, but instead of the standard client validation, it will allow running page WebMethods.

The user control has 2 new properties, compared to CustomValidator: AsyncWebMethod and AsyncWebMethodRunCondition. The first one will hold the name of the page web method, that will validate the input. The validation WebMethod is a method with a single string paremeter (the value to be validated) that returns a boolean (IsValid). It also has to be defines with a System.Web.Services.WebMethodAttribute.

For example, this is a method that was validating a user e-mail for duplicates in the database:

[WebMethod]
public static Boolean ValidateEmail(String Email)
{
    return !UserComponent.EmailExists(Email);
}

The second parameter was introduced a bit later, and is essentially optional. It cancontain a javascript boolean condition that will check if we need to validate the value. For example, when changing user details, if the user has not changed the value of the e-mail field, there is no need to make a request to the server to validate the field.

Note: Because this control uses PageMethods, a ScriptManager has to be present on the page, and it's EnablePageMethods property has to be set to true. If this is not the case, the control will throw an exception during page load.

Using the code

To demostrate the use of this control, I have created a simple page, and monitored it in firefox using Firebug. The page contains two textboxes, and two validators, as follows:

<asp:ScriptManager ID="sm" runat="server" EnablePageMethods="true" />

<asp:TextBox ID="txbValidateMe" runat="server" />
<uc:AsyncCustomValidator ID="acvValidateMe" runat="server" ControlToValidate="txbValidateMe"
    AsyncWebMethod="Validation1">Value is not capitalised</uc:AsyncCustomValidator>

<hr />

<asp:TextBox ID="txbValidateMe2" runat="server" />iAmValid will still be accepted
<uc:AsyncCustomValidator ID="acvValidateMe2" runat="server" ControlToValidate="txbValidateMe2"
    AsyncWebMethod="Validation1" AsyncWebMethodRunCondition="args.Value != 'iAmValid'">
    Value is not capitalised</uc:AsyncCustomValidator>

The first text box will always be validated using the Validation1 Page WebMethod. The second one will only be validated when it's value is different than "iAmValid".

The validation itself will check if the value entered is capitalized:

[WebMethod]
public static Boolean Validation1(String value)
{
    return (value.ToUpper()[0] == value[0]);
}

It is a very simple example, and I have only used it here to show the control :)

Demo

The advantage of this control is that the requests it makes are very lightweight, compared to AJAX callbacks, because it uses small JSON requests. When the value has to be validated, the script makes a request to the server, and the only data that is actually sent is the serialized value of the textbox:

val1.jpg

The response from the server is also very lightweight:

val2.jpgval3.jpg

In the case of the second validator, you can see that when the value is different from "iAmValid" the script does a request to the server, but in case when AsyncWebMethodRunCondition is evaluated to false, there is no request to the server whatsoever:

val4.jpgval5.jpg

Alternative

After writing this article, I have been pointed to a different approach to solve the problem. With the help of jQuery, you can use the .NET custom validator to run the same page method, and return the result asynchronously. What you have to do is point your custom validator to the following JS function:

function JQueryTestJS(source, args)
{
    $.ajax({
       type: "POST",
       async: false,
       timeout: 500,
       contentType: "application/json",
       dataType: "json",
       url: "Page.aspx/JQueryTest",
       data: '{"Value":"'+args.Value+'"}',
       success: function(result){
         args.IsValid = result.d;
       }
     });
}
In this example, you'll need a page web method called JQueryTest, with a single parameter, called Value, returning a boolean.

Points of Interest

Even with a lack of knowledge in Javascript I was able to make a simple but useful control just by doing a little research, and by forcing myself forward. A big amount of trial an error approach was used ;)

This article proves once again that simple solutions are sometimes better than the complicated ones.

History

  • 29/06/08, v1.0 - Initial release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Artiom Chilaru



Occupation: Software Developer
Location: United Kingdom United Kingdom

Other popular Validation articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 16 of 16 (Total in Forum: 16) (Refresh)FirstPrevNext
Subject  Author Date 
GeneralGood one!!!memberAshish Basran7:32 13 Aug '08  
QuestionSubmit still possible...membermaximefs6:17 24 Jul '08  
AnswerRe: Submit still possible...memberArtiom Chilaru7:53 24 Jul '08  
GeneralRe: Submit still possible...membermaximefs8:03 24 Jul '08  
GeneralRe: Submit still possible...memberArtiom Chilaru12:45 24 Jul '08  
GeneralGood article.memberRajib Ahmed19:57 1 Jul '08  
GeneralRe: Good article.memberArtiom Chilaru21:26 1 Jul '08  
GeneralAnother approach...memberMR_SAM_PIPER15:28 1 Jul '08  
GeneralRe: Another approach...memberArtiom Chilaru17:13 1 Jul '08  
GeneralRe: Another approach...memberArtiom Chilaru13:19 24 Jul '08  
QuestionIs it still Async?memberMark Gendein6:52 1 Jul '08  
AnswerRe: Is it still Async?memberArtiom Chilaru11:48 1 Jul '08  
GeneralContent of call jsonmemberacarum4:21 30 Jun '08  
GeneralRe: Content of call jsonmemberArtiom Chilaru4:24 30 Jun '08  
GeneralNice one !!memberAbhijit Jana20:47 29 Jun '08  
GeneralRe: Nice one !!memberArtiom Chilaru21:27 1 Jul '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 26 Jul 2008
Editor:
Copyright 2008 by Artiom Chilaru
Everything else Copyright © CodeProject, 1999-2008
Web08 | Advertise on the Code Project