Introduction
Client callbacks is an interesting feature of ASP.NET which allows calling server code from client-side JavaScript through XmlHTTP
. In this article, I will discuss client callback first, and then will compare its benefits with AJAX.
Using AJAX in ASP.NET 1.1 is quite a tedious task. First, you need to copy the AJAX DLL into the bin folder, then register it as an HttpHandler in Web.Config. Things do not end here because every page your are planning to use AJAX needs to be registered as well by calling AJAXUtility.RegisterForAJAXType (this.GetType ())
. And, then comes the writing of the actual client and server-side code.
In ASP.NET 2.0, the Runtime takes this responsibility of registering the HTTP handler, page types etc., and simplifies the process of client script callbacks, so in this article, I will discuss the details of it.
ASP.NET introduced a new interface named ICallBackEventHandler
. A page needs to implement this interface in order to support client callbacks. It has two methods:
RaiseCallbackEvent
: Processes a callback event that targets a control. This method is the execution point when the server code is called from the client script.
GetCallbackResult
: Returns the results of a callback event that targets a control. The result is usually returned by RaiseCallBackEvent
, and stored in some class member.
Client callbacks in action
Let's take a look at a very basic example of client callbacks in which clicking of a client side button triggers server code which returns a simple text message for display in the textbox at the client side.
Implementing ICallbackEventHandler
public partial class _Default : System.Web.UI.Page, ICallbackEventHandler
{
string callbackResult;
protected void Page_Load(object sender, EventArgs e)
{
}
public void RaiseCallbackEvent(string eventArgument)
{
callbackResult = "DotNET Rocks!";
}
public string GetCallbackResult()
{
return callbackResult;
}
}
The above code is quite simple. RaiseCallbackEvent
performs some operations and stores the result in the callbackresult
variable, which is returned by the GetCallbackResult
method. The next step is to have some JavaScript code which will trigger this callback.
<script type="text/javascript">
function GetMessageFromServer()
{
UseCallBack();
}
function JSCallback(TextBox1, context)
{
document.forms[0].TextBox1.value = TextBox1;
}
</script>
GetMessageFromServer
will trigger the server code using the UseCallback
method. This is a dynamic method generated from the code-behind; more on this later. JSCallback
is the client method which is called when the server callback completes its execution.
So, what I did here is just copy the server message in the textbox.
Clicking the following HTML button will invoke the method:
<input type="button" id="Button1" runat="server" value="Get Message"
onclick="GetMessageFromServer()"/>
Now comes the final and the most important step of using client callbacks. This step is actually responsible for emitting the JavaScript which will call the Framework method to make the actual XmlHttp
. Normally, this code fragment comes in the Page_Load
event.
protected void Page_Load(object sender, EventArgs e)
{
string cbref = Page.ClientScript.GetCallbackEventReference(this,
"arg", "JSCallback", "context");
string cbScr = string.Format("function UseCallBack(arg," +
" context) {{ {0}; }} ", cbref);
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"UseCallBack", cbScr, true);
}
The above C# code generates the following JavaScript at run time:
function UseCallBack(arg, context)
{
WebForm_DoCallback('__Page',arg,JSCallback,context,null,false);
}
This actually calls the XmlHttp
behind the scenes, which will ultimately result in a callback of the server code. So that’s it. After the server code finishes its execution, the Framework will call the specified JavaScript method to notify the completion of the callback, in this case, the function JSCallback(TextBox1, context)
.
Internals of Client Callbacks
You might be wondering where the XmlHttp
object is and how the framework calls the server callback behind the scene. Well, if you look at the generated HTML for the page, you will see an interesting script declaration:
<script src=http://www.codeproject.com/<AppName>/WebResource.axd?d=v...&t=63...0
type="text/javascript"></script>
If you open the above URL in the browser, you will see the complete definition of library functions and objects responsible for server calls and client notifications.
Another interesting thing in the previous code is the ClientScript
property of the Page
class. This property represents the instance of the ClientScriptManager
class which contains all the concerns of client side scripting and contains lots of methods useful in client-side scripting.
GetCallbackEventReference
is one of the methods which returns a reference to a client-side function that, when invoked, initiates a client callback to a server-side event.
Page Cycle in Client Callback Scripts
One of the interesting and unique features of client callback scripts is that when calling a server callback, the ASPX page loads into memory and executes normal page cycle events such as Page_Init
, Page_Load
etc. This is where client callback runs away from AJAX because in AJAX, an ASPX page is not loaded in memory, so you cannot access ViewState or the page controls. But this is not the case in client callbacks.
However, in client callbacks, a partial page cycle executes, and events such as Pre_Render
, Render
don’t fire, and it’s logical enough because we don’t want the complete page to refresh. The following diagrams will describe the page life cycle in both scenarios
Normal ASP.NET 2.0 Page Cycle
Partial Page Cycle in Client Callbacks
Client Callbacks with Parameters
You can also pass parameters to the server code; however, only one. Passing a parameter is very simple. All you need to do is pass some information to the dynamically generated method which will automatically pass it to the server:
function GetMessageFromServer()
{
var parameter = “some paramter”;
UseCallBack(parameter, "");
}
public void RaiseCallbackEvent(string eventArgument)
{
callbackResult = “some result”;
}
Client Callbacks vs. AJAX
Following are some benefits of client callbacks over AJAX.
- Since it’s undertaken by the Framework, implementation of client callbacks are consistent compared to AJAX which has various implementations and lacks standardization.
- Client callback resultant execution of page cycle means the server callback can access ViewState and form controls.
- No need to register the HttpHandlers in the configuration files.
- In client callbacks, the developer doesn’t need to write code into JavaScript. Instead, they can use a dynamic and less error prone approach of calling
Page.ClientScript.GetCallbackEventReference
.
Conclusion
Client callbacks is one of the exciting features in ASP.NET 2.0 which allows calls to server code asynchronously through XmlHttp
, which is also known as AJAX. A client callback script provides certain advantages such as access to the ViewState and the Forms
collection of an ASPX page which is not there in AJAX.
Your feedback and comments are always welcome.
References:
- A First Look at ASP.NET v. 2.0, Addison Wesley, ISBN 0-321-22896-0
- Professional ASP.NET 2.0, Wrox Press, ISBN 10: 0-7645-7610-0