1. Create a Sample Web Site
To start, launch Visual Studio 2005 and create a new ASP.NET
2.0 web site project. Name the project CallbackRefresh
(select Visual C# as the built-in language). Populate the default Web Form
(Default.aspx) with the controls as shown in Figure 6.
Figure 6: The design-time snapshot of page
Default.aspx in web site CallbackRefresh

In the above Figure we add a TextBox control to let the user
enter the category of his/her favorite animal, a Button "Search" for
the user to inquire (asynchronously from the server side) all the animals that
belong to his/her selected category, and a DropDownList control to hold and
show all the animals associated with the selected category.
Now, let us first figure out the client-side solution.
2. Client-side Programming
Herein we are mainly interested in the click event handler
associated with the above HTML input element "btnSearch," whose
source code is listed as follows:
Listing 8
function FillData()
{
var ani=document.getElementById("txtCategory").value;
<%=this.ClientScript.GetCallbackEventReference(this,"ani","FillDropDownList",null) %>;
}
It is pretty short. In the first sentence, we get the
category name that the user has just entered while the true secrecy lies in the
second sentence.
Here, we use the ASP.NET <%...> block to embed a code
block in this web page (this means it is primarily to preserve backward
compatibility with older ASP technology due to its easily resulting in complex
programming logic. However, we use it here just for demonstration.). In fact,
an embedded code block is a piece of server-side code that executes during the
page's render phase. The code in the block can execute programming statements
and call functions in the current page class. So, the above sentence is equal
to calling function Page.ClientScript.GetCallbackEventReference
within the code-behind page. This function is responsible for implementing the
callback on the client side. We have to use this method to generate client-side
code, which is a must have to instantiate the asynchronous call to the server.
When you execute this page from the browser and view the
HTML source code, you will see that it generates the following callback code
due to the above GetCallbackEventReference method call:
Listing 9
WebForm_DoCallback('__Page',ani,FillDropDownList,null,null,false);
WebForm_DoCallback is a JavaScript function that in turn
invokes the XmlHttp class methods to actually perform the callback (you can
refer to this
article to further dig into WebForm_DoCallback).
In a nutshell, the above method GetCallbackEventReference
combines the client-side function FillDropDownList
with the two server-side methods - GetCallbackResult
and RaiseCallbackEvent (both declared inside interface ICallbackEventHandler) remotely to achieve the client-side
callback mechanism.
Now, let us turn our attention to the true client-side callback
function.
Listing 10
function FillDropDownList(sAnimal)
{
document.getElementById("DropDownList1").options.length = 0;
var index;
var ani;
while (sAnimal.length > 0)
{
index = sAnimal.indexOf(",");
if (index > 0)
{
ani = sAnimal.substring(0, index);
sAnimal = sAnimal.substring(index + 1);
document.getElementById("DropDownList1").add(new Option(city, city));
}
else
{
document.getElementById("DropDownList1").add(new Option(sAnimal, sAnimal))
;
break;
}
};
}
As is easily seen here, we populate the "DropDownList1"
with data asynchronously returned from the server.
Now, continue with the server-side programming.
3. Server-side Programming
As introduced in the previous sections, we must let the
server control (here it refers to the web page itself) implement interface
ICallbackEventHandler. The following is the related code:
Listing 11
public partial class _Default: System.Web.UI.Page, ICallbackEventHandler
{
private string _data;
//……(omitted)
public string GetCallbackResult()
{
return _data;
}
public void RaiseCallbackEvent(string eventArgument)
{
switch (eventArgument)
{
case "Cat":
_data = "Felix,John,Mary,Rossy";
break;
case "Dog":
_data = "Fido,Rover,Kissy";
break;
case "Cow":
_data = "Daisy,Mighty,Hassy,Hover";
break;
case "Parrot":
_data = "Polly,Curo,Paul,Pazz";
break;
}
}
}
Here, method RaiseCallbackEvent of interface
ICallbackEventHandler is responsible for setting up values according to the
passed parameter, while method GetCallbackResult merely returns the data processed
by the previous method. The two methods, you see, have cooperatively
accomplished the server-side task associated with the client-side callback
operation.
For now, you can press F5 to start the application. Input
your favorite animal category, click on the "Search" button and you
will noticed the DropDownList control below is filled with animals that belong
to the specified category. And also, the filling process takes place asynchronously.
Figure 7: The run-time snapshot for the callback
way
