Introduction

This is the second article in a three article series focusing on AJAX or Asynchronous JavaScript and XML. If you haven’t read Part 1, I encourage you to read Part 1 of this article series. In Part 1, we had covered the client side portion of AJAX, specifically the JavaScript object used to initiate asynchronous web requests. The goal of this article is to provide something easy for the server side (ASP.NET) developer to integrate into their code (preferably without a lot of fancy or proprietary workarounds).

The Good Stuff

We will be going over the example code (see Download source files above) shown in listings 1 and 2, Article.aspx and Article.aspx.cs respectively. The code samples are shown in C# but the technique can be used with any .NET compliant language.

Article.aspx

Article.aspx is an example of how you might apply AJAX to a real web application. More and more web sites are requiring users to register before they can access most of the sites’ content. This usually involves selecting a username and password as well as entering some other information like an email address or zip code. Rarely does a site allow two users to have the same username. So let’s say I choose “JohnDoe” as my username, I click the button to sign up, wait a while, only to have the web page reload saying that the username I have requested is not available. This process could go on for a while until I choose a unique username. AJAX allows us to validate the username as the user is typing it. No posting back to the server and no downloading a complete list of unavailable usernames. Article.aspx shows this “instant validation” in action.

The JavaScript

To validate the username being entered, we need to send the current username to the server, wait for the request to complete, then take action based on the result. I have simplified this process by creating the CallBackObject (see AJAX Was Here – Part 1 for the details).

Here we are creating a new CallBackObject and telling the object, “When my web request is completed, I want you to run the function Cbo_Complete”, and “If anything bad happens during the request, I want you to run the function Cbo_Error”. Since the web request is asynchronous, we don’t know when exactly the server will complete our request, so we setup the OnComplete event so we don’t have to sit and twiddle our thumbs.

When our web request does finish, we want to let the user know. Our web request will return True if the username entered is available, or False if the username entered is not available. If the username is available, we show a positive message with green text, otherwise, we show a negative message in red text.

The function CheckUsername starts the asynchronous request (or Call Back) to the server. First, we make sure that the username in question is not blank, and then we call Cbo.DoCallBack, passing the ID of the username input box (more on this later). If the username is blank, we cancel any Call Back currently in process, and clear any messages.

Finally, within the HTML, we set the onkeyup attribute of our username textbox to execute CheckUsername and pass the current value of the textbox. We use onkeyup so that we can provide instant feedback to the user as they are entering their desired username.

That is all the client side code required to make our AJAX example work.

The ASP.NET

The beauty of the CallBackObject is that it essentially allows JavaScript code to fire server side events. Let’s look at the HTML snippet again.

Notice how we set OnTextChanged (which is a server side event) to txtUsername_TextChanged. As we will see in a moment (see Listing 2), txtUsername_TextChanged is an ASP.NET event written in C# that determines if the value of txtUsername is an available username. This event is raised from the client using JavaScript by this line:

Cbo.DoCallBack('txtUsername', '');

Isn’t that cool? You are raising server side events with client side code without reloading the entire page. Let’s look a little deeper at txtUsername_TextChanged.

First off, we check to see if the current request is a Call Back, using the CallBackHelper (included in the source files). This is exactly the same as using Page.IsPostBack, you want to do different things depending on the context of the request. Next, we get the value of txtUsername and pass it to our IsUsernameAvailable function. This function returns a boolean indicating whether or not the username is available. Finally, we write that value back to the client using CallBackHelper.Write. Notice how we wrap the processing in a try/catch block and if anything bad happens, we use CallBackHelper.HandleError. This makes sure that the client is notified of errors.

IsUsernameAvailable is a simple test function, normally you would lookup the requested username in a database to see if it was valid.

I have also but an asp:button on the page to show the difference between our call back implementation and the standard ASP.NET implementation. If you click the “Check Username Availability” button, you post back the entire page to validate the username, which may take a while longer, plus the user cannot continue filling out the form until the server returns the results.

Test It out

Cruise on over to this site to see AJAX in action. Type a letter, and you should get a visual indicator of the availability of the username. Continue typing and you should be updated as you go (try bill or pierce for an unavailable username). You can also click the button to perform the same action using a standard post back.

But what does it all mean?

We could have returned any string to the client, including XML. In this example we only need a simple true/false to indicate if the username is available. Another example might be sending a zip code from the client and returning the city and state from the server. The sky is the limit now that you can interact with server side code from the client.

Conclusion

ASP.NET takes care of the event plumbing for us. As long as you use ASP.NET controls and implement standard events, SelectedIndexChanged, TextChanged, Click, you can easily use AJAX in your ASP.NET applications with the CallBackObject and CallBackHelper.

And then?

If you’re not already tired of reading my rants, check out Part 3 of the article series when we create an Auto Complete Textbox. Auto Complete Textbox is an ASP.NET control that completes your text as you type. Awesome!

History

2005-04-21 – Initial release.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Comments and Discussions

I've followed your directions in order to create a unique username checking control. I have it successfully wired up in that it calls back correctly, but I always get "Viewstate is invalid and may be corrupted" coming back as an error.

This site will help you to find all the resource to learn and know all about Ajax technology, by providing you with the latest Ajax projects, latest Ajax tutorial, Ajax articles, Ajax Forum and Ajax news. \

I found this portal, it's about ajax technology it represents all the projects that implemented using ajax technology, and libraries that may help in creating ajax projects
http://www.ajaxprojects.com
Hazem Torab

This site will help you to find all the resource to learn and know all about Ajax technology, by providing you with the latest Ajax projects, latest Ajax tutorial, Ajax articles, Ajax Forum and Ajax news.

I found this portal, it's about ajax technology it represents all the projects that implemented using ajax technology, and libraries that may help in creating ajax projects
http://www.ajaxprojects.com
Hazem Torab

It appears that this article is no longer a part of the code project. I would like to see modifications to this code that have resolved some of the issues relating to multiple instances on a single page...or suggestions on newer 2.0 friendly ajax helpers.

The Asynchronous communication of AJAX gives the user the feeling of a normal desktop application, what is good. Also the way the communication works with AJAX, allows us to send less data.

As side effect. this approach has in ASP.NET a lot of overhead on the server side. AJAX sends every time the complete form with VIEWSTATE back to the server. The server builds up all the components (OnInit) before the (by AJAX triggered) event is called.

So, however the callbacks could give the user the feeling of close interaction, the callbacks could give an extreme load of the server, causing the total performance go down and the users start complaining again. Especially when the interface is build up from the database.

Are my assumptions correct here and how could we fix these performance drain?

Alas Steven, while I hope this article is a good read and I hope it gets people thinking, you are 100% correct. There is a lot of overhead involved in firing an ASP.Net event which is why the responsiveness of my implementation is poor for medium to complex interfaces.

Most other AJAX/.Net implementations I've seen involve a call back to another page, without sending ViewState or other extraneous information.

That being said, my goal was to make it simple to use (and I hope I've achieved that

The only performance enhancements I've thought about were client and server side caching. But, too much client side caching defeats the purpose of AJAX and server side caching still requires a call to the server side method.

You should be able to avoid the additional overhead by calling Response.End() after you write the response text to it (I presume the callback handler does this in it's Write() method). Once this is called the thread will be immediately aborted, so the Render() function will never be called. This should save a lot on the overhead as the response will only contain the text that you have explicitly written to it

This code works on most major browsers. It doesn't work on konquerer under KDE on *nix (Linux, etc.), because its engine is braindead and strips unrecognized tags from the DOM (no other major engine does this). This is bad behavior on the browser's part, and the only way to compensate for it is to use string concatanation or serve the documents as XHTML. ASP.NET 2.0 can serve XHTML, or you can install a 3rd party filter (google for it -- believe it's on codeproject, but not positive).

Because this invokes a web service, you have the SOAP overhead, but as you can see there's not much.

Well...You would probably want to call the server side method from the client as a result of some sort of client input? i.e. Button click, lost focus, keystroke, etc. That is why I chose this approach. All of those are events.

There are other AJAX implementations for .Net that don't require events. See the "Another AJAX for .Net" posts below.

One timer is a one-shot. This means you must reset it after each use. The other timer is an interval timer.

For the suggested approach, you want to use the one-shot timer. If you don't, you'll have bad results. You also need a semaphore (flag) to indicate that you are already processing an HTTP request, since you can't control how long the request might take.

After making the XmlHttpRequest.send, you want to repeat this code to reschedule the timer until the operation is complete.

When you make the initial request to the server, the server needs to spawn a thread and return something that the client can provide to check up on status (a "handle" or transaction id or whatever you want to call it).

Subsequent requests need to include the handle, and use it to find the thread processing the request and get its status.

Finally, you need to eventually clean it up. The client can do this when its done with the request; if it doesn't, the server needs to eventaully.

I have tried to implement a solution similar to this but I am getting the error "Thread was being aborted" after the CallBackHelper.Write method is called.

I have a client-side timer loop which calls the callback method. That method then runs on the server and checks a db parameter. My intention was then to allow that thread to sleep for a configurable number of seconds before executing again ( on the server ). Obviously the server loop returns as soon as a change occurs and is also configured to run the CallBack.Write method within the client loop interval.

I've had success calling ASP.NET Web Service methods via javascript objects. If you're new to web services, visit www.asp.net for a simple "get-started" tutorial on creating a web service. An ASP.NET web service can be as sinple as one ASP.NET script in an .asmx file. It can then be called via the HTMLHttp object via POST or GET methods, or you can just set the URL string on an <XML> tag (with URL query parameters). Either one can be set to asynchronous mode and initiated via javascript.

This is pretty neat stuff! It is a little similar to some workarounds I have done using the MS Webservice behaviour to return an XML dataset which I then transform into a table and use to set a DIVs innerHTML.

However, this is a far more generic approach.

On that point, I think a good direction for it to take is to hide the plumbing completely by developing a complete set of ASP.NET controls which inherit from the existing ones. Instead of having to check whether the the call is a callback in their event handlers, these controls could provide new events which are only invoked when the call is a callback.

New properties could also be added to specify the callback behaviour of the control (e.g. disabled, enabled for change, enabled for lost focus etc.). The appropiate client side script would be rendered for the control depending on the property setting.

I'm very shock when I saw the article you wrote. It's very great. But I had a question:

The CheckUsername(Username) javascript function just tell Cbo.DoCallBack('txtUsername', '')
and without any server event name: txtUsername_TextChanged.

How did they kmow which ASP.NET event will be invoked.
And I had tried to remove : OnTextChanged="txtUsername_TextChanged"
and the strange thing happen: the Server event btnCheckUsername_Click was be invoked

Why? How should I identify which event to be invoked.
If the server control has more than one server event, which one will be called?

Cbo.DoCallBack('txtUsername', '') tells ASP.Net (on the server side) that the Textbox with ID of 'txtUsername' is responsible for the Call Back. ASP.Net then looks at all the events you have implemented for txtUsername (i.e. OnTextChanged) and raises that event by running the method you specifiy (txtUsername_TextChanged). I realize it's a little bit "automagical" but that's why .Net rocks.

Another question:
Inside ASP.NET, how did it know which event should be invoked?
Is by differents of the ViewState's value and all of the elements' values, right?
So, that why your callback object has to return the viewstate, right?

Exactly correct rex. The ViewState must be sent so that ASP.Net knows that the value of the Textbox has changed and thus, the TextChanged event can be raised.

As to your question about which event would be raised if there are multiple server-side events on a call back control. I haven't tested it but I believe all events would be raised. Thus it is important to check if it is a callback using the CallBackHelper in your code.