Enhance your Website with ASP.NET AJAX Extensions

Microsoft's ASP.NET AJAX Extensions provide developers with a quick and simple way to add AJAX functionality into any ASP.NET Website. In this article, Dan Wahlin demonstrates how to use the UpdatePanel control, which performs asynchronous postback operations that update a portion of a page rather than the entire page itself.

AJAX (Asynchronous JavaScript and XML) is arguably one of the most hyped technology acronyms around. The primary advantage of using AJAX is that page refreshes can be minimized, allowing users to get the information they need quickly and easily through a more rich and functional interface. Ajax accomplishes this by using JavaScript and an XmlHttp object to send data asynchronously from the browser to the Web server and back. So, although AJAX has a lot of marketing-hype surrounding it, the benefits it offers can’t be denied.

Microsoft’s ASP.NET AJAX Extensions provide developers with a quick and simple way to add AJAX functionality into any ASP.NET Website, without requiring in-depth knowledge of JavaScript or other AJAX technologies. This article will demonstrate how you can add AJAX capabilities into a new or existing Website by using a new ASP.NET AJAX server-side control called the UpdatePanel. You’ll see how the UpdatePanel control can be used to allow portions of a page to be updated without requiring the entire page to be posted back to the server and reloaded in the browser. Additional topics covered include:

  • The role of the ScriptManager control
  • Nesting UpdatePanel controls
  • Triggering asynchronous requests
  • Providing progress indicators to end users
  • Interacting with the UpdatePanel on the client-side, using the PageRequestManager class.

Let’s get started by discussing how to get the ASP.NET AJAX Extensions installed and configured.

Installing the ASP.NET AJAX extensions

Before you can use the ASP.NET AJAX UpdatePanel control you need to install the ASP.NET AJAX Extensions, available from http://ajax.asp.net/, on your development machine. Once installed, a new Website template titled “ASP.NET AJAX-Enabled Website” will appear when you first create a new Website using Visual Studio .NET 2005 or Web Developer Express. Select this template when you want to add ASP.NET AJAX functionality into Web pages.

The ASP.NET AJAX Extensions rely upon special HTTP handlers and modules to handle and respond to asynchronous requests sent from a browser. By creating a new ASP.NET AJAX Website in Visual Studio .NET, a web.config file will automatically be created that contains references to a ScriptResource.axd handler as well as a ScriptModule module. The ScriptResource handler dynamically loads JavaScript files into pages that leverage AJAX features while ScriptModule manages HTTP module functionality that is related to request and response messages.

If you’d like to upgrade an existing Website and add ASP.NET AJAX functionality into it you’ll need to ensure that you manually update your site’s web.config file with the proper entries. The easiest way to do this is to create a new ASP.NET AJAX-Enabled Website (as mentioned earlier) and then copy the AJAX-specific portions of web.config to your original web.config file. You’ll of course need to ensure that the ASP.NET AJAX Extensions are also installed on your production server before deploying the updated site.

Adding AJAX functionality into ASP.NET Web Forms

Before the ASP.NET AJAX Extensions were released, developers had to rely on custom AJAX libraries to AJAX-enable a Web site. While these libraries were quite powerful and worked in cross-browser scenarios, they often required a familiarity with JavaScript, and even XML or Web Service technologies. Some of the frameworks were/are susceptible to CSRF (Cross Site Request Forgery) attacks, whereby a hacker could hi-jack AJAX messages and potentially steal information. Fortunately, the ASP.NET AJAX Extensions offer a secure AJAX framework that includes a new server control called the UpdatePanel that hides JavaScript complexities.

The UpdatePanel control allows you to focus on the functionality of your application rather than on programming and understanding AJAX-specific technologies. It performs asynchronous postback operations that update a portion of a page rather than the entire page itself. This technique is often referred to as “partial-page updates“. The UpdatePanel control works by intercepting postback requests triggered by the page and converting them into asynchronous postback calls, which are then sent to the server using the browser’s XmlHttp object. It relies on client-side scripts managed by the ASP.NET AJAX framework to perform this asynchronous functionality.

Before using the UpdatePanel control you must first add into your page an important ASP.NET AJAX control, called the ScriptManager. The ScriptManager handles loading all of the necessary client-side scripts that are required by the UpdatePanel and other AJAX controls in order to make asynchronous AJAX calls. You can drag a ScriptManager control onto a page from the VS.NET toolbox or add it directly into the source code as shown next:

Once a ScriptManager control is added, an UpdatePanel control can then be defined in the page. The UpdatePanel acts as a container in much the same way as the standard ASP.NET Panel control. However, content embedded within the UpdatePanel is wrapped within a template named ContentTemplate. Any content placed within the ContentTemplate is automatically AJAX-enabled. This means that button click or other postback events triggered by controls in the template will be intercepted and converted into asynchronous AJAX calls to the server.

Listing 1 demonstrates how to use an UpdatePanel control in a page in order to AJAX enable a GridView, which allows paging through customer data:

Listing 1. Using the UpdatePanel control and ContentTemplate.

As users page through customer records in the GridView control, or sort different columns, the UpdatePanel control automatically handles AJAX-enabling the call resulting in a partial-page update rather than a complete page refresh.

Displaying progress

Although the UpdatePanel is simple to use, you must take the end user into account when using it, especially if you don’t know how long an asynchronous postback may take to complete. Long requests may cause an end user to think that their request has failed or hung and they may start the request again, navigate to a different page or even close the browser. The solution is to provide them with a visual progress indicator so that they know that their request is being processed.

The ASP.NET AJAX Framework includes the UpdateProgress control that can be used to provide users with a visual indication of whether or not their request is still being processed. Listing 2 shows an example of using the UpdateProgress control to display an animated image to an end user, while a Web Service is called that retrieves album information.

Listing 2. Using the UpdateProgress control.

You’ll see that the UpdateProgress control has a ProgressTemplate that contains the content to show to the end user, while the UpdatePanel asynchronous postback is processed. Any content type of content (images, flash movies, videos, etc.) can be placed inside of the template. In cases where you’d like the content to take up a fixed amount of space on the page as opposed to dynamically being added, you can set the DynamicLayout property to false.

The UpdateProgress control shown in Listing 2 is embedded directly within the target UpdatePanel. However, it can be embedded elsewhere in the page and linked to the appropriate UpdatePanel by setting its AssociatedUpdatePanelID property to the ID of the UpdatePanel. In cases where quick partial-page updates may occur, and you don’t want the UpdateProgress control to show its content, you can set the DisplayAfter property to the number of milliseconds that you’d like it to wait before displaying progress content. DisplayAfter defaults to a value of 500 milliseconds.

Figure 1 demonstrates the end-user effect of using the UpdateProgress control. As the UpdatePanel is being refreshed with album information from a call to the Amazon.com Web Service, a progress indicator is displayed directly below the Artist textbox.

386-Figure1.gif

Figure 1. Using the UpdateProgress control to give visual feedback to end users as a call is made to the Amazon.com Web Service.

Nesting UpdatePanel controls

Multiple UpdatePanel controls can be added into a page in cases where different sections need to make AJAX calls to the server to avoid reloading the entire page. In addition to having multiple UpdatePanels in a page, you can also nest UpdatePanels to provide more granular AJAX functionality. For example, you may want to show a GridView control that displays information and allows a user to drill-down into additional details to achieve a master-details style view. Figure 2 shows an example of doing this using two GridView Controls.

386-Figure2.gif

Figure 2. Creating a master-details view of customer and order data.

To accomplish this type of master-details view, an UpdatePanel is nested inside of a GridView‘s ItemTemplate, as shown in Listing 3. As a user clicks the “View Orders” LinkButton, within each row shown in Figure 2, the GridView within the nested UpdatePanel is made visible. Any paging or sorting requests made within the nested UpdatePanel control will cause it to reload new data by making asynchronous AJAX requests, while data in the parent GridView control is left untouched.

Listing 3. Creating a master-details view of data using nested UpdatePanel control.

The UpdatePanel control exposes an UpdateMode property that defaults to a value of “Always”. This means that any asynchronous request triggered anywhere within the page will cause the UpdatePanel to refresh itself. In cases where this behavior isn’t desired, the UpdateMode property can be assigned a value of “Conditional” so that only triggers associated with the control or child controls embedded within the control’s ContentTemplate can cause it to be refreshed through an asynchronous postback. Other controls outside of the UpdatePanel will not cause it to be refreshed. Additional information about UpdatePanel triggers is covered in the next section.

The parent UpdatePanel control in Listing 3 has its UpdateMode set to Conditional so that any asynchronous postback operations caused by the nested UpdatePanel or by other controls in the page do not cause the parent GridView control to be refreshed. This minimizes the number of asynchronous postback requests made to the server.

Using triggers

While controls inside of an UpdatePanel control can cause it to perform asynchronous postbacks, other controls defined outside of the UpdatePanel can also act as “triggers” that cause the UpdatePanel to refresh itself with new data. Two types of triggers exist for UpdatePanels including the AsynchronousPostBackTrigger control and PostBackTrigger control.

An AsynchronousPostBackTrigger causes an UpdatePanel‘s content to be updated asynchronously when a specific control’s event is fired such as a Button’s click event or a DropDownList‘s SelectedIndexChanged event. A PostBackTrigger causes a regular postback operation to occur that reloads the entire page. When AJAX-enabling your Websites you’ll normally want to use the AsynchronousPostBackTrigger to stop postback operations from occurring.

Listing 4 shows how to define a DropDownList control as a trigger that can perform a refresh of the UpdatePanel‘s contents. This is done by using the AsynchronousPostBackTrigger control. Notice that the ID of the DropDownList control is defined using the ControlID property, and the event that causes the partial-page update of the UpdatePanel is defined using the EventName property. When the SelectedIndexChanged event fires, an asynchronous postback is made to the server and the UpdatePanel‘s content is reloaded.

Listing 4. Defining triggers to perform partial-page updates on the contents of an UpdatePanel.

In cases where you’d like to prevent controls defined within an UpdatePanel‘s ContentTemplate from triggering an asynchronous postback operation, you can set the UpdatePanel‘s ChildrenAsTriggers property to false and the UpdateMode to “Conditional”. Any events raised by child controls in the ContentTemplate of the control will be ignored, while events raised by triggers such as the one shown in Listing 4 will cause a partial-page update to occur, if needed.

Listing 5 shows an example of setting the ChildrenAsTriggers property to false to prevent LinkButtons clicked within a DataList control from updating the contents of an UpdatePanel. While the LinkButtons don’t cause the UpdatePanel to refresh itself, they do cause another UpdatePanel defined in the page to be refreshed so that additional details about employees can be shown to the end user (see Figure 3).

Listing 5. Using the ChildrenAsTriggers property to stop child control’s of an UpdatePanel from triggering an asynchronous postback operation.

The results of this are displayed in Figure 3. When a territory is clicked, employees in that territory will be shown.

386-Figure3.gif

Figure 3. LinkButtons defined in an UpdatePanel trigger a separate UpdatePanel to display additional details about employees.

The UpdatePanel where the controls are defined is not updated since the ChildrenAsTriggers property is set to false.

Handling UpdatePanel events on the client

The UpdatePanel control handles all asynchronous requests to the server, so you don’t have to worry about writing JavaScript code. This is great from a productivity and maintenance standpoint but there will be times when you want to know when an UpdatePanel request is going to start, or when data has returned and is about to be updated in the page. For example, you may want to access data returned by an UpdatePanel and use it to make another asynchronous postback request. Or, you may want to animate the UpdatePanel as a request is started so that the end user sees what is happening and knows when content in a particular area of a page has been refreshed. All of this can be done by using a JavaScript class provided by the ASP.NET AJAX script library, called the PageRequestManager.

The PageRequestManager lives in the Sys.WebForms namespace in the ASP.NET AJAX script library and allows you to tie into requests and responses processed by one or more UpdatePanels in a page. It’s responsible for managing partial-page updates that occur within a page as well as managing the client page life-cycle. By using it you can tie into several different events and act upon them. PageRequestManager also exposes properties and methods that can be used to check if asynchronous requests are in process. It can also be used to abort existing requests and even cancel pending requests.

Events exposed by the PageRequestManager class include initializeRequest, beginRequest, pageLoading, pageLoaded and endRequest. The following table provides more details about these events and when they are fired.

Event

Description

initializeRequest

Raised when an asynchronous postback is first initialized. This event can be used to cancel requests in cases where another request is already in process.

beginRequest

Raised when an asynchronous postback begins. This event can be used to animate an UpdatePanel container within a page to provide users with a visual cue that an asynchronous postback request is starting.

pageLoading

Raised after data is received from an asynchronous postback request but before the data is updated in the page. This event can be used in cases where you’d like to change data returned from the server using JavaScript or provide an effect on the UpdatePanel to signify that content is about to be updated.

pageLoaded

Raised when data in a page is updated after a synchronous or asynchronous request.

endRequest

Raised after an asynchronous postback request is completed. Any errors that occurred during the request can be processed here.

To access the PageRequestManager you can call its getInstance() method on the client-side as shown next:

Once the PageRequestManager object is available, you can define event handlers for the different events that it exposes and attach to them. Listing 6 shows how to attach an event handler to the endRequest event and access data returned from the asynchronous postback request.

Listing 6. This code shows how to attach an event handler to the endRequest event of the PageRequestManager.

Once a request is completed, errors are checked and if none are found, data returned by the request is accessed and passed to another method for processing.

Notice that the parameter signature for the EndRequest() event handler mirrors the one found in the .NET framework where the sender of the event as well as any event arguments are passed as parameters. The eventArgs parameter can be used to check if any errors occurred during the request by calling the error property which can be used to access the HTTP status code of the request. If a 500 error is found then the code accesses the error message by calling the message property, marks that the error has been handled and shows the error message to the end user. If no error occurs, a hidden field, named hidField, which is returned from the asynchronous postback, is accessed to get a value needed by a GetMap() method, which is used to display a Virtual Earth map.

The PageRequestManager can also be used to abort or cancel asynchronous postback requests by handling the initRequest event. Listing 7 shows an example of canceling a request in cases where an UpdatePanel is in the process of making a request and the end user is impatiently clicking a Refresh button.

Listing 7. This code shows how the PageRequestManager‘s initRequest event can be used to cancel a pending asynchronous postback request.

The code in Listing 7 starts by accessing an instance of the PageRequestManager in the Application’s init phase and ensuring that an asynchronous postback isn’t already in progress on the page. If no asynchronous postback is occurring, the InitRequest event handler is attached to the initializeRequest event. Once the InitRequest handle is called, a call is made to the PageRequestManager‘s isInAsyncPostBack property and the event argument’s postBackElement property (the event argument is of type InitializeRequestEventArgs). The isInAsyncPostBack property returns a Boolean value indicating if an asynchronous postback is currently in progress and postBackElement property provides access to the control that triggered the request.

If an asynchronous postback is already in progress and a new request is triggered by a button with an ID of btnRefresh, the pending request is cancelled by assigning a value of true to set_cancel. A message is then displayed to the end user letting them know that a request is already being processed and that they need to wait. The PageRequestManager class can be used to perform several other actions such as animating an UpdatePanel before a request is made and after the response is processed.

Conclusion

The ASP.NET AJAX Framework provides a simple and productive way to add AJAX functionality into new or existing Websites. With a minimal amount of effort you can make your applications perform more efficiently and provide end users with a richer experience than traditional Web applications by using partial-page updates.

In this article you’ve seen how the ScriptManager and UpdatePanel controls can be used to make asynchronous postbacks from the browser to the server and how different types of triggers can initiate the requests. You’ve also seen how UpdatePanel controls can be nested to provide a master-details style view of data and how the UpdateMode and ChildrenAsTriggers properties can control how and when an UpdatePanel‘s content is updated. Finally, you’ve seen how the PageRequestManager client-side class can be used to notify you of partial-page update requests and responses.