Home
    Shop
    Advertise
    Write For Us
    Affiliate
    Newsletter
    Contact

Client Side Callbacks in ASP.NET 2.0

ASP.NET 2.0 includes a new Client Callback feature that enables you to retrieve page values and populate them to an already-generated page with out reconstructing page. This makes it possible to use on a page with out going through the entire post back cycle; that means you can update your pages without completely redrawing the page.

 

End users will not see the page flicker and reposition, and the pages will have a flow of a thick client application. It is an interesting feature that allows invoking server side code from Client side JavaScript using XmlHTTP.

Postback and Callback

Before we appreciate the feature of Callback, let's see how current Postback feature in a typical ASP.NET page works

In a normal Postback situation, when any page event is triggered on ASP.NET page, a HTTP post request will be sent to web server, which then processes the request with the IPostbackEventHandler and runs the request through a series of page events. These events include loading the state (ViewState), processing data, processing Postback events and finally rendering the page to be interpreted by the consuming browser.

This process completely reloads the page in the browser, which is what causes the flicker and the realignment to the top of the page.

But in a Client call back situation, any page event is triggered on ASP.NET page; it causes the event to be posted to a script event handler (a JavaScript function) that sends off an asynchronous request to the web server for processing. ICallbackEventHandler runs the request through a pipeline similar to what is used with the Postback- but you notice that some of the larger steps (such as rendering the page) are excluded from the process chain. After the information is loaded, the result is returned to the script callback object. The script code then pushes this data into the web page using JavaScript's capabilities to do this without refreshing the page.

Let's see an example to see how Callback feature works. Following page will generate Current date when end user clicks the button on the form, the callback service is initiated and current date is populated into the textbox. You can download sample Callback ASP.NET project, used in this tutorial.

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Client Callback</title>
    <script type="text/javascript" >
    function GetDate()
    {
    UseCallback();
    }
    function GetDateFromServer(TextBox1, context)
    {
    document.forms[0].TextBox1.value= TextBox1;
    }
     </script>
   
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <input id="Button1" type="button" onclick="GetDate()" value="Get Date" /> 
        <br />
        <br />
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    </div>
    </form>
</body>
</html>
Web form html listing, Default.aspx


Partial Class _Default
    Inherits System.Web.UI.Page
    Implements System.Web.UI.ICallbackEventHandler
    Dim _callbackResult As String = Nothing
 
 
    Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
        Return _callbackResult
    End Function
 
    Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
        _callbackResult = Now.ToString()
    End Sub
 
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim cbReference As String = Page.ClientScript.GetCallbackEventReference(Me, "arg", "GetDateFromServer", "context")
        Dim cbScript As String = "function UseCallback(arg,context)" & _
        "{" & cbReference & ";" & "}"
        Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "UseCallback", cbScript, True)
    End Sub
 
End Class
CodeBehind Listing


Output Listing

Clicking the button on the page invokes the client callback capabilities of the page, and the page then makes an asynchronous request to the code behind of the same page. After getting a response from the part of the page, the client script takes the retrieved value and places it inside the text box - all without doing a page refresh.

Now take a look at the .aspx page, which simply contains an HTML button control and a TextBox server control. Notice that a standard HTML button control is used because a typical <asp:button> control does not work here. No worries. When you work with the HTML button control, just be sure to include an onclick event to point to the JavaScript function that initiates this entire process:

<input id="Button1" type="button" onclick="GetDate()" value="Get Date" />

You don't have to do anything else with the controls themselves. The final thing to include in the page is the client-side JavaScript functions to take care of the callback to the server-side functions. GetDate() is the first JavaScript that's instantiated. It starts the entire process by calling the name of the client script handler that is defined in the page's code behind. A string type result from GetDate() is retrieved using the GetDateFromServer() function. GetDateFromServer() simply populates the string value retrieved and makes that the value of the Textbox control - specified by the value of the ID attribute of the server control(TextBox1):

function GetDate()
    {
    UseCallback();
    }
 
function GetDateFromServer(TextBox1, context)
    {
    document.forms[0].TextBox1.value= TextBox1;
    }

Now turn your attention to the code behind.

The page class of the web page implements the System.Web.UI.ICallbackEventHandler interface.

Partial Class _Default
    Inherits System.Web.UI.Page
    Implements System.Web.UI.ICallbackEventHandler
 
........code here
End Class

This interface requires you to implement a couple of methods - the RaiseCallbackEvent, and the GetCallbackResult methods, both of which work with the client script request. RaiseCallbackEvent enables you to do the work of retrieving the value from the page, but the value can be only of type string.

Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
        _callbackResult = Now.ToString()
End Sub

The GetCallbackResult is the method that actually grabs the returned value to be used:

Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
        Return _callbackResult
End Function

In addition, the Page_Load event includes the creation and placement of the client callback script manager (the function that will manage requests and responses) on the client:

Dim cbReference As String = Page.ClientScript.GetCallbackEventReference(Me, "arg", "GetDateFromServer", "context")
        Dim cbScript As String = "function UseCallback(arg,context)" & _
        "{" & cbReference & ";" & "}"
        Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "UseCallback", cbScript, True)

The function placed on the client for the callback capabilities is called UseCallback(). This string is then populated to the Web page itself using the Page.ClientScript.RegisterClientScriptBlock that also puts <script> tags around the function on the page. Make sure that the name you use here is the same name you use in the client-side JavaScript function presented earlier.

Now, you have a page that refreshes content without refreshing the overall page. This opens the door to a whole new area of possibilities. One possible caveat is that the callback capabilites described here use XmlHTTP and, therefore, the client browser needs to support XmlHTTP. Because of this, this .Net Framework 2.0 introduces the SupportCallBack and the SupportXmlHTTP properties.


Tutorial toolbar:  Tell A Friend  |  Add to favorites  |  Feedback  |   


comments powered by Disqus