October 17, 2005 12:10 AM

ASP.NET 2.0 Callbacks

Create Rich User Interfaces with Client-side Callbacks
DevConnections
Rating: (1)

ControlFreak

LANGUAGES:VB.NET

ASP.NETVERSIONS: 2.0 (Pre-Release)

 

ASP.NET 2.0 Callbacks

Create Rich User Interfaces with Client-side Callbacks

 

 

Page postbacks are by far the most common way to pass databetween the client and server in an ASP.NET application. The simplicity of thistechnique is appealing, but the reality is that it?s often inefficient anddisorienting for the user. If a single value on a Web page needs to be updated,why must the entire page (and the user) suffer through a complete round trip tothe server?

 

Even if performance is not an issue for your application,there are plenty of other reasons for ditching postbacks whenever possible. Forstarters, they are just plain ugly. Even with the speediest servers there areoften perceptible flashes and delays while the browser posts back the page,retrieves a slightly modified version of the page, then redraws it completely. Youmay have also noticed that the Back button doesn?t always operate as the userexpects in an ASP.NET application. This is entirely due to unnecessarypostbacks. There are also scrolling problems; when the user has scrolled thepage down and the page posts back, they end up at the top of the page again ? andmust scroll back down manually unless the developer goes out of their way toimplement extra code to make it appear as if the page didn?t post back.

 

Now that it?s been established that postbacks should beavoided whenever possible, what?s the best way to get around them?

 

One of the most efficient solutions is to transfer allrequired data to the browser and use client-side script to manipulate itdynamically without bothering the server at all. While this can be a nicesolution for developers who are fluent in JavaScript, large amounts of datafrequently prohibit this from being a viable option for dial-up users and othersuch outliers. In such cases, however, there is one reasonably optimal solution ...

 

Client-side Callbacks

For years it?s been possible to use client-side code tocall back to the server without posting back the entire page, but thecomplexity has traditionally scared most developers away. The new client-sidecallback technology in ASP.NET 2.0 alleviates many of the headaches and reducesthe amount of code necessary to make it happen.

 

The classic XMLHTTP callback technology is wrapped byASP.NET 2.0 callbacks, exposing a relatively simple interface. You may haveheard the buzzword ?AJAX? recently,which is a technology nearly identical to XMLHTTP. Certainly in philosophy theyare identical, permitting out of band callbacks so Web pages can updatethemselves fluidly (see Figure 1).

 


Figure 1: ASP.NET 2.0 callbacks wrapstandard XMLHTTP technology, which allows Web pages to update themselvesfluidly.

 

Automatic Callbacks with TreeViews and GridViews

While you canuse ASP.NET 2.0 callbacks with virtually any Web control, the technique is easiest to use with the new GridView andTreeView controls because the technology is built in. Using client-sidecallbacks with these two controls is as simple as setting a couple properties.

 

The new GridView control can sort and change pages withoutposting the page back to the server. The GridView control provides anEnableSortingAndPagingCallback property that enables its server-side sortingand paging routines to be called out of band; only the GridView control callsback to the server and refreshes while the rest of the page stays put. Unfortunately,this functionality is broken in Beta 2 of ASP.NET 2.0, but it should be fixedby the final release.

 

The new TreeView control also implements the client-sidecallback functionality. In fact, the ASP.NET 2.0 client-side callbacktechnology was originally developed specifically for the TreeView control. Luckilyfor us, the developers had enough foresight to design it in a generic way so itcould be used with other controls, as well.

 

TreeView nodes can retrieve their child nodes from theserver and expand dynamically, without requiring a full page refresh. To enablethis functionality, the EnableClientSideScript and PopulateNodesFromClientproperties of the TreeView control must be set to True, and thePopulateOnDemand property of the applicable tree node(s) must also be set toTrue. Additionally, the TreeView?s server-side TreeNodePopulate event must bepopulated with code that retrieves the node data, places the data into a nodestructure, and, finally, adds the node structure to the ChildNodes collection. Thenode structure can be created by adding TreeNode objects to the ChildNodescollection of the parent TreeNode. Figure 2 contains a simplified version ofsuch code; Figure 3 shows the page in action.

 

Sub TreeView1_TreeNodePopulate(ByVal sender As Object, _

 ByVal e AsSystem.Web.UI.WebControls.TreeNodeEventArgs) _

 HandlesTreeView1.TreeNodePopulate

   Select Casee.Node.Value

      Case"Software"

          Dim NewNode AsNew TreeNode

          NewNode.Text ="Antivirus"

          e.Node.ChildNodes.Add(NewNode)

      Case"Hardware"

          Dim NewNode AsNew TreeNode

          NewNode.Text ="Keyboards"

          e.Node.ChildNodes.Add(NewNode)

   End Select

End Sub

Figure 2: TheTreeView control can call back to the server to retrieve the data necessary toexpand tree nodes, then place code in the server-side TreeNodePopulate event toadd the nodes dynamically. It can then update its own user interface withoutrequiring the page to post back.

 


Figure 3: The child nodes in thisTreeView control were retrieved dynamically at run time by client-side codecalling back to the server, thus avoiding a costly page postback.

 

Roll Your Own Callbacks

It?s sure handy to have client-side callback functionalityimplemented automatically in the GridView and TreeView controls, but what aboutall the other Web controls? With a moderate amount of effort, any Web controlcan be enhanced with client-side callback functionality.

 

The first step is to put the necessary client-side piecesin place. In most cases, some kind of client-side control will need to triggerthe event. It?s important to not choose a control that causes a postback,because this will negate the client-side callback. So a button Web controlwould be a bad choice, but an HTML button works just fine. The runat=?server?attribute is necessary to attach a client-side event to the button at run time fromserver-side code:

 

<button runat="server" id="btn">GetTime</button>

 

The button won?t do anything until it?s wired up with theappropriate code to call back to the server, receive the result, and displaythe result. The code in Figure 4 does exactly that.

 

Protected Sub Page_Load(ByVal sender As Object, _

 ByVal e AsSystem.EventArgs) Handles Me.Load

 

 'Define JavaScriptfunctions that will recieve the result

 Dim sCallBack As String =_

   "functionMyCallBack(result, context){alert(result);}"

 Dim sErrCallBack AsString = _

   "functionMyErrCallBack(result,context){alert(result);}"

 

 'Output the JavaScriptfunctions to the page

 Page.ClientScript.RegisterClientScriptBlock(Me.GetType, _

   "MyCallBack",sCallBack, True)

 Page.ClientScript.RegisterClientScriptBlock(Me.GetType,_

   "MyErrCallBack", sErrCallBack, True)

 

 'Attach button's clientevent to the JavaScript functions

 btn.Attributes("OnClick") = _

  Page.ClientScript.GetCallbackEventReference(Me, _

  "'Parm'","null", "MyCallBack", "MyErrCallBack", True)

 

 If Not Page.IsPostBackThen

   'Outputs the time thepage was initially rendered

   Response.Write("Page Rendered at " & Date.Now.ToString)

 End If

End Sub

Figure 4: Thiscode attaches JavaScript functions to the client-side button that permits it tocall back to the server and display the result.

 

The code starts by defining a JavaScript function thatwill be called with the result of the server?s response. It also defines asimilar JavaScript function that will be called in the event of an unexpectederror. In the second code block these events are actually output to the pagevia the new ClientScript property of the Page object. By collecting relatedfunctions into a single place and adding quite a few new functions, this newproperty makes managing client scripts easier than it was in ASP.NET 1.x.

 

In the third code block of Figure 4, the button is wiredup to perform the call back to the server. The GetCallBackEventReference methodis used to make this happen. This function accepts several parameters, asdefined in Figure 5.

 

Parameter

Type

Description

control

System.Web.UI.Control

The page or control that?s implementing the callback reference.

argument

String

Optionally, a string parameter may be passed from the client to the server-side function.

clientCallback

String

The name of the client-side function that will receive the result of a successful callback.

context

String

The name of the client-side function that will be called before the call back to the server.

clientErrorCallback

String

The name of the client-side function that will be called if there is an error attempting to call back to the server.

useAsync

Boolean

Specifies whether the callback should be synchronous or asynchronous.

Figure 5:GetCallBackEventReference parameters.

 

The final step is for your server-side code to implementthe ICallbackEventHandler interface. Its associated RaiseCallbackEvent is theserver-side function that gets called by the client-side script; Figure 6 showsan example. Before this function gets called, the page state gets instantiatedin a fairly normal way. That is, ViewState, Session, control values, and allthe other forms of server context are filled so you can use them as you wouldin any standard page postback. (This perhaps has slightly more overhead thancalling a Web service, but the tradeoff is that the logic can be kept insidethe applicable page, thereby simplifying future maintenance.)

 

Partial Class MyPage

 InheritsSystem.Web.UI.Page

 Implements ICallbackEventHandler

 '(Page_Load event listedin Figure 4)

 

 Public FunctionRaiseCallbackEvent(ByVal eventArgument _

    As String) As StringImplements _

    System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent

 

    Return "Theserver time is " & Date.Now.ToString

 End Function

End Class

Figure 6: Pagesthat support client-side callbacks must implement the ICallbackEventHandler andits associated RaiseCallbackEvent function.

 

The RaiseCallbackEvent function accepts a string parameterand returns a string parameter. What gets put in these strings is entirely upto you. These parameters could contain simple text, numeric characters, XML,comma-delimited text, empty strings, or virtually anything imaginable that canbe represented with text.

 

Keep in mind that the user won?t see any visual changesyou make to controls from within this function because HTML is not renderedback to the client. For visual changes to happen after a client-side callback,they must be done using client-side code.

 

Also keep in mind that if you have multiple controls on apage that use callbacks, they will all call to the same RaiseCallbackEvent. It?sup to you to sort out which control is calling back and what it wants.

 

Figure 7 shows the fully functional program in action. Theserver time is displayed directly on the page when the page originally renders.When the user clicks on the button, the page does not post back nor refresh,but it does call back to the server to retrieve the current server time anddisplay it in a message box.

 


Figure 7: The server can becontacted for updated information at any time without requiring the page toreload. In this example, the page retrieves the current time from the server.

 

If you view the source of the page you?ll notice somehidden fields that are implanted by ASP.NET to help implement the feature. Youneedn?t worry about these because it?s all handled automatically. You?ll alsonotice a script reference that ASP.NET uses to implement the XMLHTTP operationsthat are happening behind the scenes. The reference looks a bit like this:

 

<scriptsrc="/MyWeb/WebResource.axd?d=leT47j4&amp;t=632493"

 type="text/javascript"></script>

 

Future Compatibility

The code snippets in this article were developed withVisual Studio 2005 Beta 2. It?s possible that there could be some syntaxchanges before the final release. Additionally, it?s been said that ASP.NET 2.0callbacks will support browsers beyond only Internet Explorer, although that?snot yet the case in Beta 2.

 

The new GridView and TreeView controls have first-classcallback support. It?s too bad Microsoft didn?t build such high-qualitycallback support into the rest of the Web controls, but at least a callbacksolution is now feasible if you?re willing to jump through a few coding hoops.

 

Client-side callbacks certainly hold a lot of promise forenriching user interfaces all across the Web. Now users will no longer have tosuffer through postbacks that seem (to them) to happen at arbitrary moments. Backbuttons can work intuitively once again, and users never again need to bedisoriented by having their scroll positions reset. It does take a moderateamount of effort, but your users will love you for it.

 

Steve C. Orr is anMCSD and a Microsoft MVP in ASP.NET. He?s been developing software solutionsfor leading companies in the Seattlearea for more than a decade. When he?s not busy designing software systems orwriting about them, he can often be found loitering at local user groups andhabitually lurking in the ASP.NET newsgroup. Find out more about him at http://SteveOrr.netor e-mail him at mailto:Steve@Orr.net.

 

 

 

Add a Comment

There are no comments to display. Be the first one!
You must log on before posting a comment.

Are you a new visitor? Register Here

advertisement




Comments from the DevConnections Community

Join our community of development pros.

Windows problem

I all, I have a problem on my Windows Vista that began afetr the purchase of an external Hard Disk Freecom. A few days afetr the purchase I discon...

Most Recent Posts

GOOGLE LINKS
SPONSORED LINKS
FEATURED LINKS