Chapter 38. Using Server-Side ASP.NET AJAX

Users of modern web applications have changed quite a bit since the first days of the web. When the web was new and when functional, commercial websites were few and far between, the users of web applications were a generally complacent and easy-to-please audience.

Today, web application users don’t just want more, they demand more. They demand that websites be fast, responsive, and interactive. They don’t want an entire page to reload just because a small piece needs to be changed. Most important, they don’t want to sit and wait in front of an unresponsive user interface while background processing takes place.

To meet the increasing demands of web users, a new technology called AJAX (Asynchronous JavaScript and XML) was created. This enabled already-rendered web pages to make asynchronous calls and retrieve XML, which could then be used to modify the existing page. The first evidence of this type of technology actually showed up in Microsoft Outlook’s web access product. Since then, web application users have been demanding unprecedented levels of interactivity and responsiveness.

The key to giving users this responsiveness lies in the combination of asynchronous messaging calls and JavaScript (or jQuery or any number of JavaScript-based frameworks). In this chapter you learn about one small piece of this puzzle: Microsoft’s server-side Ajax controls such as the UpdatePanel, a control that enables postbacks within a region of the page to modify only that portion of the page and not interrupt the user’s overall experience. We also provide an overview of two controls that support the UpdatePanel: the Timer and the UpdateProgress.

The Ajax Vision

ASP.NET is a server-side technology for building web applications. Almost all the work happens on the web server and not the web browser. Whenever you perform an action in an ASP.NET page—such as clicking a button or sorting a GridView—the entire page must be posted back to the web server. Any significant action on a page results in a postback.

If you think about it, this is incredibly inefficient. When you perform a postback in an ASP.NET page, the entire page must be transported across the Internet from browser to server. Next, the .NET class that corresponds to the page must re-render the entire page again from scratch. Finally, the finished page must be sent back across the Internet to the browser. This whole long, slow, agonizing process must occur even if you are updating a tiny section of the page.

Using a server-side technology such as ASP.NET results in a bad user experience. Every time a user performs some action on a page, the universe temporarily freezes. Whenever you perform a postback, the browser locks, the page jumps, and the users must wait patiently twiddling their thumbs while the page is reconstructed. All of us have grown accustomed to this awful user experience; however, we would never design our desktop applications in the same way.

When the members of the ASP.NET team invented ASP.NET in the late 1990s, there was good reason to embrace the server side. Getting a page that was written in JavaScript to work consistently across different browsers, and even across different versions of the same browser, was difficult. The server side was safe and reliable.

However, we’ve reached a tipping point. Web developers are discovering that if they want to build truly great applications, they need to leave the safety of the server side and enter the wilds of the client side. Today’s popular web applications such as Facebook, Google Gmail, and YouTube all rely heavily on Ajax-based functionality.

An Ajax application is a client-side web application written using native browser technologies such JavaScript and the DOM. A pure Ajax application is a web application that consists of a single page and performs all its communications with the web server through web service calls.

Note

Applications that use client-side technologies such as Flash, Flex, Java applets, and Silverlight don’t count as Ajax applications because these are proprietary technologies. An Ajax application must use native browser technologies.

Unlike a server-side web application, an Ajax application can be responsive to user interaction. If a user clicks a button in a server-side web application, the button Click event doesn’t actually happen until the page gets posted back to the server. In a server-side application, the button Click event gets shifted in time and space. In a client-side Ajax application, on the other hand, the button Click event happens when it happens: right on the browser.

In an Ajax application, the user interface layer is located in the browser (where it should be). The business logic and data access layers are located on the server. The user interface layer accesses the business logic layer through web services.

Server-Side Ajax Versus Client-Side Ajax

Microsoft has a complicated relationship with Ajax. On the one hand, the company wants to provide its existing ASP.NET developers with an easy way to implement Ajax functionality without having to learn JavaScript. On the other hand, Microsoft recognizes that the client is a powerful area to enable developers. Therefore, it wants to provide web developers with the tools they need to build pure client-side Ajax applications. For these reasons, Microsoft has both a server-side Ajax framework and a client-side Ajax framework.

If you want to retrofit an existing ASP.NET application to take advantage of Ajax, you can take advantage of Microsoft’s server-side AJAX framework. To take advantage of the server-side framework, you don’t need to write a single line of JavaScript code. You can continue to build ASP.NET pages with server-side controls in the standard way. You learn how to take advantage of the server-side AJAX framework in this chapter.

The advantage of the server-side framework is that it provides existing ASP.NET developers with a painless method of doing Ajax. The disadvantage of the server-side framework is that it doesn’t escape all the problems associated with a server-side framework. You still have to run back to the server whenever you perform any client-side action.

The Microsoft client-side AJAX framework (which we discuss in Chapter 40, “Client-Side AJAX with jQuery”) embraces the client side. When building applications with the Microsoft client-side AJAX framework, you must build the application by using JavaScript. The advantage of building applications with the client-side framework is that you can build rich and responsive web applications. You can build web applications with the same rich interactivity as a desktop application.

Debugging Ajax Applications

Before we start discussing the Microsoft AJAX frameworks, you need to be aware of two crucial debugging tools. Debugging Ajax applications presents challenges not present in a normal server-side application. If an Ajax call fails, you won’t necessarily know. You need a way of monitoring the Ajax calls that happen between the browser and server.

The first tool is Fiddler. You can download this tool (for free) at http://www.fiddlertool.com. Fiddler enables you to view HTTP requests and responses, including Ajax calls. Fiddler works by installing itself as a proxy between your web browser and the rest of the universe. You can use Fiddler with Internet Explorer, Mozilla Firefox, Opera, Safari, and just about any other browser.

After you install Fiddler, from Microsoft Internet Explorer, you can launch the tool by selecting Tools, Fiddler2. After Fiddler launches, every browser request and response is recorded in the Fiddler Web Sessions pane. You can click a request and then click the Session Inspector tab to see the full request and response (see Figure 38.1).

Figure 38.1. Using Fiddler to inspect an Ajax request and response.

image

Note

If you can’t get Fiddler to capture page requests from localhost, try adding a period directly after localhost in the browser address bar. For example, make a request that looks like this:

http://localhost.:6916/Original/Feedback.aspx

The other critical Ajax debugging tool is Firebug, which is a free Firefox extension. You can download Firebug by launching Firefox and selecting Tools, Add-ons. Next, click the Get Extensions link. Finally, enter Firebug into the search box and follow the installation instructions.

Firebug, like Fiddler, enables you to monitor Ajax calls, but it enables you to do much more. After you install Firebug, you can click the bug icon at the bottom right of the Firefox browser to open Firebug (see Figure 38.2).

Figure 38.2. Using Firebug in Mozilla Firefox.

image

Firebug has several useful features for debugging JavaScript applications. For example, it enables you to set breakpoints in JavaScript scripts, inspect DOM elements, and determine which CSS rules apply to which elements in a page. Right now, however, I want you to notice that you can use Firebug to monitor Ajax requests and responses. If you click the Net tab and the XHR tab, every Ajax call appears in the Firebug window. You can click a particular Ajax request to see the full request and response interaction between browser and server.

Using the UpdatePanel Control

Microsoft’s server-side AJAX framework consists of one main control: UpdatePanel. The UpdatePanel control enables you to update a portion of a page without updating the entire page. In other words, it enables you to perform partial-page rendering.

Let’s start with a super-simple example of a page that uses the UpdatePanel control. The page in Listing 38.1 contains a ScriptManager control and an UpdatePanel control. The UpdatePanel control contains a single Button control. When you click the button, only the content contained in the UpdatePanel control is refreshed (see Figure 38.3).

Figure 38.3. Using the UpdatePanel control.

image

Listing 38.1. UpdatePanelSimple.aspx

images

The page in Listing 38.1 displays the current time both inside and outside the UpdatePanel control. When you click the button, only the time within the UpdatePanel control is refreshed.

Let’s look at a more realistic example that just begs for some Ajax (see Figure 38.4). The page in Listing 38.2 does not use any of the ASP.NET AJAX controls. It contains two cascading DropDownList controls. The first DropDownList enables you to pick a state, and the second DropDownList enables you to pick a city. The list of cities changes depending on the state selected.

Figure 38.4. A page with cascading DropDownList controls.

image

Listing 38.2. CascadingDropDownsNoAjax.aspx

images

images

When you select a state using the first DropDownList control, there is a click, and the page posts back to itself to populate the second DropDownList control with matching cities. Clearly, the user experience here is less than optimal. All work must stop while the page performs a postback.

Let’s fix up this page with some Ajax. The page in Listing 38.3 is exactly the same as the page in Listing 38.2, except for two changes. First, the page now contains a ScriptManager control. Second, and more important, the DropDownList controls in Listing 38.3 are wrapped inside an UpdatePanel control.

Listing 38.3. CascadingDropDownsAjax.aspx

images

images

images

In Listing 38.3, when you select a new state with the first DropDownList control, matching cities display in the second DropDownList control. However, there is no click and there is no noticeable postback. The browser doesn’t freeze, and the page does not jump. Everything happens smoothly and professionally through the magic of Ajax.

The ScriptManager control in Listing 38.3 adds the necessary JavaScript scripts to enable Ajax. Anytime you create a page that uses Ajax, regardless of whether you are doing server-side or client-side Ajax, you’ll add a ScriptManager control to the page.

The UpdatePanel control is the control that is doing all the Ajax work here. It hijacks the normal postback that would happen when you select a new item in the first DropDownList control. The UpdatePanel hijacks the normal postback and performs a “sneaky” postback to grab the new content in the background.

Let’s look at another page that takes advantage of the UpdatePanel control. The page in Listing 38.4 represents a simple customer feedback form (see Figure 38.5). The page contains a FormView control and a GridView control. The FormView control renders the insert form, and the GridView control is used to display previous customer responses. You can sort the contents of GridView in order of the different columns.

Figure 38.5. Entering customer feedback into an Ajax-enabled form.

image

Listing 38.4. Feedback.aspx

images

images

images

images

Because the UpdatePanel control in Listing 38.4 contains both the FormView and GridView, you can interact with the page without performing a single postback. When you submit the form, the form data is submitted back to the server using Ajax. When you sort the columns in the GridView, the sorted rows are retrieved from the server through an Ajax call.

The UpdatePanel control has six important properties:

ChildrenAsTriggersGets or sets a Boolean value that indicates whether child controls should trigger an asynchronous postback automatically.

ContentTemplateContainerGets the container for the UpdatePanel control’s ContentTemplate. You can add controls to the ContentTemplate programmatically using this property.

IsInPartialRenderingGets a Boolean value indicating whether the UpdatePanel is rendered in response to an asynchronous postback.

RenderModeGets or sets a value that indicates whether the contents of an UpdatePanel should be enclosed in an HTML <div> or <span> tag. Possible values are Block (the default) and Inline.

TriggersGets a list of controls that trigger the UpdatePanel to perform either an asynchronous or synchronous postback.

UpdateModeGets or sets a value indicating when the content of the UpdatePanel is updated. Possible values are Always (the default) and Conditional.

The UpdatePanel also supports the following single important method:

Update()Causes the UpdatePanel to update its contents.

You learn how to take advantage of these properties and methods in the following sections.

Specifying UpdatePanel Triggers

By default, an UpdatePanel hijacks any postbacks that any of its child controls performs. For example, if a Button control is contained in an UpdatePanel, the UpdatePanel hijacks the button Click event and performs an Ajax call instead of the normal postback.

You can cause an UpdatePanel to refresh its contents from a control located outside of the UpdatePanel by specifying a trigger. For example, the page in Listing 38.5 contains a Button control outside of an UpdatePanel that causes the UpdatePanel to refresh its content.

Listing 38.5. TriggerUpdatePanel.aspx

images

images

The UpdatePanel in Listing 38.5 includes a Triggers subelement that contains a single AsyncPostBackTrigger. This trigger points to the Button control located outside of the UpdatePanel named btnUpdate. Because the UpdatePanel contains this trigger, clicking the Button control causes the UpdatePanel to refresh its contents.

If you want, you can prevent the UpdatePanel from refreshing its contents unless you have explicitly created a trigger. If you set the UpdatePanel control’s ChildrenAsTriggers property to the value false, you must explicitly create a trigger to update the contents of the UpdatePanel.

The UpdatePanel supports two types of triggers: AsyncPostBackTrigger and PostBackTrigger. The AsyncPostBackTrigger causes an asynchronous (Ajax) postback. The PostBackTrigger causes a normal entire-page postback.

You’ll rarely use a PostBackTrigger. The only situation in which it makes sense to use a PostBackTrigger is when you need to mix buttons that cause asynchronous postbacks and normal postbacks in the same UpdatePanel control. For example, because you cannot perform a file upload without performing a normal entire-page postback, if a file-upload button is contained in an UpdatePanel, you need to create a PostBackTrigger for the file-upload button.

Nesting UpdatePanel Controls

One UpdatePanel can contain another UpdatePanel. You can nest UpdatePanels to your heart’s content, just like Russian nesting dolls.

Nesting UpdatePanel controls is useful when you want to control how much of a page gets refreshed during an asynchronous postback. Sometimes, you might need to update only a tiny portion of a page, and other times you might need to update the entire page.

For example, the page in Listing 38.6 contains two nested UpdatePanels. The outer UpdatePanel contains a DropDownList, FormView, and ListView control. The inner UpdatePanel contains only the ListView control (see Figure 38.6).

Figure 38.6. Page with nested UpdatePanel controls.

image

Listing 38.6. NestedUpdatePanels.aspx

images

images

images

images

images

images

When you select a movie by using the DropDownList control, the entire page is updated. When you add a new comment to the movie with the ListView control, on the other hand, only the comments portion of the page is updated.

There are two UpdatePanel controls. The first UpdatePanel control has an ID of upOuter. It includes a trigger that points to the DropDownList control used to select a movie. This UpdatePanel control has its UpdateMode property set to the value Conditional. If the UpdateMode property was not set to this value, the outer UpdatePanel would refresh its content when the Add Comment button contained in the inner UpdatePanel control was clicked.

The inner UpdatePanel is named upInner. This UpdatePanel surrounds the ListView used to display the form for adding and displaying movie comments. When you add a new movie comment, only the comments area of the page is updated and not the entire page.

The page, the outer UpdatePanel, and the inner UpdatePanel all display the current time. When you select a new movie, the time displayed by both the outer and inner UpdatePanel—but not the page—changes. When you add a new comment, only the time displayed by the inner UpdatePanel changes.

In general, for performance reasons, you should place the smallest possible area that you need to update inside of an UpdatePanel control. The larger the area contained in an UpdatePanel, the more content that must be passed across the Internet when the UpdatePanel is updated. By nesting UpdatePanel controls, you have more granular control over the content that gets updated in a page.

Updating UpdatePanels Programmatically

The UpdatePanel control includes an Update() method. You can use this method to update the content of an UpdatePanel programmatically during an asynchronous postback.

Two properties determine when an UpdatePanel control updates its contents: UpdateMode and ChildrenAsTriggers. If you set the UpdateMode property to the value Conditional and you set ChildrenAsTriggers to the value false (and you don’t define any triggers), the only way to update an UpdatePanel control’s content is by calling the Update() method.

For example, the page in Listing 38.7 enables you to search movies by title. The page contains two UpdatePanel controls. The first UpdatePanel control contains a TextBox control and a Button control. The second UpdatePanel control contains a GridView control, which uses a Movie class (which can be found in the source code on the book’s website) to communicate with the datbase. When you click the button, the Button Click event is raised on the server through an asynchronous postback. The second UpdatePanel that contains the GridView of results is updated if, and only if, any results are found that match the search query.

Listing 38.7. UpdateUpdatePanel.aspx

images

images

UpdatePanels and JavaScript

You must take special care when using JavaScript with UpdatePanel controls. If you use the standard methods of the ClientScriptManager class for working with JavaScript, they will fail when called during an asynchronous request.

For example, I often use the Page.ClientScript.RegisterStartupScript() method from my server-side code to inject a JavaScript script into a page dynamically. The page in Listing 38.8 contains a Delete All Files button. When you click the button, and the FileHelper.DeleteAll() method returns true, a JavaScript alert box displays the message All Files Deleted Successfully! (see Figure 38.7).

Figure 38.7. Displaying a JavaScript alert.

image

Listing 38.8. ShowAlert.aspx

images

Unfortunately, the page in Listing 38.8 does not work when the Button control is wrapped in an UpdatePanel. The JavaScript alert never appears after you click the button. The page fails silently.

If you need to inject JavaScript into a page when performing an asynchronous postback, you need to take advantage of the methods exposed by the ScriptManager class. The ScriptManager class duplicates all the standard JavaScript methods of the ClientScriptManager class, including the following:

RegisterArrayDeclaration()Enables you to add a JavaScript array to the page.

RegisterClientScriptBlock()Enables you to add an inline JavaScript script right after the opening <form> tag.

RegisterClientScriptInclude()Enables you to add a JavaScript <script src=""> tag to a page.

RegisterClientScriptResource()Enables you to add a reference to a JavaScript file embedded in an assembly.

RegisterExpandoAttribute()Enables you to register a tag expando.

RegisterOnSubmitStatement()Enables you to register a JavaScript script that is executed when the form is submitted.

RegisterStartupScript()Enables you to add an inline JavaScript script right before the closing <form> tag.

The page in Listing 38.9 demonstrates how you can add JavaScript from the server to a page when performing an asynchronous postback.

Listing 38.9. ShowAlertUpdatePanel.aspx

images

images

In Listing 38.9, the Button control is wrapped in an UpdatePanel. When you click the button, the ScriptManager.RegisterStartupScript() method adds the JavaScript alert to the page dynamically.

UpdatePanel Server-Side Page Execution Life Cycle

You need to understand that a server-side page goes through its normal page execution life cycle when you perform an asynchronous postback. The Page PreInit, Init, Load, and PreRender events are raised for an asynchronous postback in just the same way as these events are raised for a normal postback.

The page in Listing 38.10 logs each server event and displays the log in a BulletedList control (see Figure 38.8).

Figure 38.8. Viewing an asynchronous postback’s server lifecycle.

image

Listing 38.10. ServerLifecycle.aspx

images

images

images

When you first open the page in Listing 38.10, each page event is listed in the BulletedList control. Next to each event, you see the word False. The ScriptManager.IsInAsyncPostBack property displays whether the page is processed within a normal postback or an asynchronous postback.

The page includes an UpdatePanel that contains a Button control. Clicking the button initiates an asynchronous postback. After you click the button, the exact same list of events appears in the BulletedList control. The exact same events are raised during an asynchronous postback as are raised during a normal postback.

Note

ScriptManager.IsInAsyncPostBack has the value False when the PreInit event is raised during an asynchronous postback. This IsInAsyncPostBack property is updated after this event. (So it is just wrong.)

UpdatePanel Client-Side Page Execution Life Cycle

A page that contains a ScriptManager control not only has a server-side page execution life cycle, it also has a client-side page execution life cycle. The following series of events happen on the client-side:

Application.initRaised when a page is first requested. This event is not raised during an asynchronous postback.

PageRequestManager.initializeRequestRaised before an asynchronous request to the server starts.

PageRequestManager.beginRequestRaised before an asynchronous request to the server starts.

PageRequestManager.pageLoadingRaised after an asynchronous response is received from the server but before UpdatePanel content is updated.

PageRequestManager.pageLoadedRaised after an asynchronous response is received from the server and after UpdatePanel content is updated. Also raised during the initial page request.

Application.loadRaised during both normal and asynchronous postbacks.

PageRequestManager.endRequestRaised after an asynchronous response both when there is and when there isn’t an error.

Application.unloadRaised before the user leaves or reloads the page.

Two client-side objects raise client life-cycle events: Sys.Application object and Sys.WebForms.PageRequestManager. The Sys.Application events happen in a page regardless of whether the page contains UpdatePanel controls. The Sys.WebForms.PageRequestManager events are tied to UpdatePanels.

The page in Listing 38.11 illustrates when each of these client-side events occurs. The page takes advantage of ASP.NET AJAX’s client-side trace support. When each client event occurs, Sys.Debug.trace() is used to write a message to the Trace Console. Figure 38.9 shows the page after the Async Postback button is clicked.

Figure 38.9. Viewing an asynchronous page’s client execution lifecycle.

image

Listing 38.11. ClientLifecycle.aspx

images

images

images

Because we are discussing client-side events, we have moved over into the JavaScript world. The script in Listing 38.11 has to be written in JavaScript because it executes within the browser and not on the server.

Different information is available during each client-side event. You can access the event information by reading the properties of the second parameter passed to the event handler. What follows is the event information passed to each event handler.

InitializeRequestEventArgs

Passed to the PageRequestManager.initializeRequest event handler. Supports the following properties:

cancelEnables you to cancel the current asynchronous postback.

postBackElementThe element that caused the asynchronous postback.

requestThe request object used to perform the asynchronous postback.

BeginRequestEventArgs

Passed to the PageRequestManager.beginRequest event handler. Supports the following properties:

postBackElementThe element that caused the asynchronous postback.

requestThe request object used to perform the asynchronous postback.

PageLoadingEventArgs

Passed to the PageRequestManager.pageLoading event handler. Supports the following properties:

dataItemsThe data items registered with the ScriptManager.RegisterDataItem() method.

panelsDeletingThe array of UpdatePanel elements being deleted.

panelsUpdatingThe array of UpdatePanel elements being updated.

PageLoadedEventArgs

Passed to the PageRequestManager.pageLoaded event handler. Supports the following properties:

dataItemsThe data items registered with the ScriptManager.RegisterDataItem() method.

panelsCreatedThe array of UpdatePanel elements created.

panelsUpdatedThe array of UpdatePanel elements updated.

ApplicationLoadEventArgs

Passed to the Application.load event handler. Supports the following properties:

componentsThe array of components created since the last time the Application.load event was raised.

isPartialLoadIndicates whether the page is executing in the context of an asynchronous postback.

EndRequestEventArgs

Passed to the PageRequestManager.endRequest event handler. Supports the following properties:

dataItemsThe data items registered with the ScriptManager.RegisterDataItem() method.

errorThe error, if any, that occurred during the asynchronous postback.

errorHandledEnables you to suppress the error.

responseThe response associated with the asynchronous postback.

Note

You can detect whether a page is executing within the context on an asynchronous postback within client code by using the PageRequestManager.isInAsyncPostBack property.

The page in Listing 38.12 illustrates how you can take advantage of these event properties. The page contains two UpdatePanel controls. During an asynchronous call, the border of the active UpdatePanel turns the color orange. When the asynchronous call completes, the border of the updated UpdatePanel turns green.

Note

Later in this chapter, you learn how to use the UpdateProgress control to display an UpdatePanel’s progress. The method described in this section of handling client events directly is useful when you want to display a custom progress indicator.

Listing 38.12. UpdatePanelCustomProgress.aspx

images

images

images

images

images

When the page in Listing 38.12 first loads in your browser, the PageRequestManager pageLoaded event is raised and the prm_pageLoaded event handler executes. This event handler assigns a default CSS class (named normal) to each of the UpdatePanel controls in the page. The list of UpdatePanels is retrieved from the PageLoadedEventArgs.panelsCreated property.

If you click the first button, the border around the first button turns orange until the asynchronous postback completes and the border turns green. The same thing happens when you click the second button.

When you click a button, the PageRequestManager beginRequest event is raised and the border around the button turns orange. After the response is returned from the server, the PageRequestManager pageLoaded event is raised and the border around the button turns green. The list of updated UpdatePanels is retrieved from the PageLoadedEventArgs.updated property.

What happens if you click both buttons in rapid succession? In that case, you are attempting to perform two simultaneous asynchronous postbacks. Unfortunately, the UpdatePanel does not support multiple simultaneous asynchronous postbacks. By default, the last postback performed will abort all previous postbacks.

Canceling the Current Asynchronous Postback

As you learned in the previous section, you can perform at most one asynchronous postback in a page at a time. By default, the last postback wins. If you initiate a new postback while a previous postback is being processed, the previous postback is aborted.

If you want to reverse this logic, and give precedence to the first postback over future postbacks, you can cancel every postback that occurs after the first postback until the first postback completes. The page in Listing 38.13 illustrates how to cancel an asynchronous postback in the event handler for the PageRequestManager.initializeRequest event (see Figure 38.10).

Figure 38.10. Canceling an asynchronous postback.

image

Listing 38.13. UpdatePanelCancel.aspx

images

images

Using similar logic, you can always give precedence to one UpdatePanel over another. Listing 38.14 contains client-script that always gives precedence to the btnSubmit1 button over any other button that causes an asynchronous postback in the page. (The entire page is included in the source code on the book’s website).

Listing 38.14. UpdatePanelPrecedence.aspx

images

If you click the second button (btnSubmit2) immediately after clicking the first button (btnSubmit1), the second asynchronous postback is canceled.

Aborting the Previous Asynchronous Postback

You can explicitly abort a previous asynchronous postback by using the PageRequestManager abortPostBack() method. Explicitly aborting a postback is useful when you want to associate a Cancel button with an asynchronous postback (see Figure 38.11).

Figure 38.11. Aborting an asynchronous postback with a Cancel button.

image

For example, the page in Listing 38.15 contains two buttons. The first button retrieves your fortune. The oracle, however, is slow. It takes 3 seconds for the oracle to deliver a new fortune. If you want to cancel the new fortune during these 3 seconds, you can click the Cancel button.

Listing 38.15. UpdatePanelAbort.aspx

images

images

images

Passing Additional Information During an Asynchronous Postback

You can pass additional items from the web server to the web browser during an asynchronous postback. Passing additional items is useful when the area that you need to update on a page does not fall into a neat little rectangle. For example, you might want to update a page’s title or a page’s meta tags based on the results of an asynchronous query.

The page in Listing 38.16 contains a DetailsView control that you can use to navigate the contents of the Movie database table. The DetailsView control is contained inside of an UpdatePanel control so that a postback does not happen when you navigate to a new movie.

Listing 38.16. UpdatePanelDataItem.aspx

images

images

images

When you navigate to a new movie, both the browser title bar, and the page heading are updated to display the title of the new movie (see Figure 38.12). The title and heading are updated by passing a data item that represents the movie title during the asynchronous postback.

Figure 38.12. Updating a page’s header and title asynchronously.

image

Handling UpdatePanel Errors Gracefully

Sometimes things go terribly wrong. The Internet gets clogged, an application’s database server goes down, and so on. How do you recover from these types of errors gracefully in an Ajax application?

By default, if an error occurs during an asynchronous postback, a JavaScript alert box appears that displays an error message. This is a jarring experience in a production application.

You have several options for avoiding this default experience: You can configure a custom error page; you can handle the error on the server side; or you can handle the error on the client side. Let’s examine each of these options.

First, if you configure a custom error page for your application, by default the custom error page applies to asynchronous postback errors. You enable a custom error page by adding the following element to the system.web section of your web configuration file:

<customErrors mode="On" defaultRedirect="ErrorPage.aspx" />

This element enables a custom error page for both local and remote requests. Any unhandled exceptions in any page cause the browser to be redirected to a page named ErrorPage.aspx.

The page in Listing 38.17 throws an exception when you click the button located in the UpdatePanel control. If you open the page in Listing 38.17 with a custom error page enabled, the browser is redirected to the ErrorPage.aspx page automatically.

Listing 38.17. UpdatePanelError.aspx

images

images

You can disable custom error pages in the case of an asynchronous postback by adding an AllowCustomErrorRedirect attribute to the ScriptManager tag, like this:

image

Instead of redirecting the user to an error page, you can customize the error message that the user sees. You can customize the error on both the server and the client.

On the server, you can handle the ScriptManager control’s AsyncPostBackError event to customize the error message transmitted to the client. For example, the page in Listing 38.18 modifies the error message to be a generic one.

Listing 38.18. UpdatePanelErrorServer.aspx

images

images

The page in Listing 38.18 cloaks the actual server-side error message with a generic message. The error message displayed by the page is still not professional. Most likely, you’ll want to customize the error message even more when the error is displayed on the client.

The page in Listing 38.19 illustrates how UpdatePanelErrorServer.aspx you can customize an error message on the client. The page displays an error message directly above the UpdatePanel when an asynchronous postback fails (see Figure 38.13).

Figure 38.13. Customizing a client-side error message.

image

Listing 38.19. UpdatePanelErrorClient.aspx

images

images

images

Before leaving this section, I need to mention one last property supported by the ScriptManager control related to errors: AsyncPostBackTimeOut. This property determines the amount of time in seconds before an asynchronous postback times out. The default value is 90 seconds. You might want to set this value to a briefer duration.

UpdatePanel Performance

The UpdatePanel hides the normal page postback by performing an asynchronous (sneaky) postback. Even though you can use the UpdatePanel to trick your users into believing that a postback is not occurring, it is important that you do not trick yourself.

You can use either of the two debugging tools discussed earlier in this chapter to view the Ajax request and response that occur during an asynchronous postback. For example, Listing 38.20 contains a typical Ajax request, and Listing 38.21 contains a typical Ajax response.

Listing 38.20. Ajax Request

images

Listing 38.21. Ajax Response

images

images

images

images

images

The Ajax request and response in Listing 38.20 and Listing 38.21, respectively, were captured using Fiddler after sorting by the Name column in the Feedback.aspx page.

I’m including the full request and response traffic to make a point. No one would describe either the request or response as tiny. A lot of text must be passed back and forth from the browser to the server and back again when an UpdatePanel control refreshes its content.

A big chunk of both the request and response consists of ViewState, which is passed to the server during an asynchronous postback, just like it is passed during a normal postback. The server-side page executes just like it executes during a normal postback. Therefore, the server-side page needs the ViewState to execute correctly.

To improve the performance of asynchronous postbacks performed by an UpdatePanel, consider disabling ViewState for the controls contained within the UpdatePanel. Every ASP.NET control has an EnableViewState property. You can always set this property to the value False to disable ViewState.

The following table compares the size of the asynchronous request and response with the GridView control’s ViewState enabled and disabled:

image

As the table clarifies, you save about 1,000 bytes for both the request and response by disabling ViewState.

The disadvantage of disabling ViewState for a control such as a GridView is that it forces GridView to make a new database call whenever you sort or page GridView. However, one easy way to reduce the load on your database server is to take advantage of caching. If you cache all the records displayed by GridView on the server, and disable ViewState; then you reduce your network traffic and you don’t place any additional load on your database server.

Note

To learn more about caching, see Chapter 29, “Caching Application Pages and Data.”

When working with the UpdatePanel, you should never forget that the server-side page undergoes its normal page execution life cycle whenever an asynchronous postback occurs. If you perform an expensive database lookup in your Page_Load() method, that lookup occurs with each asynchronous call to your server.

You can avoid performing unnecessary server-side work during an asynchronous postback by taking advantage of the ScriptManager control’s IsInAsyncPostBack property. You can use this property to detect whether the page is executing in the context of a normal postback or an asynchronous postback.

Using the Timer Control

The ASP.NET AJAX Timer control enables you to refresh an UpdatePanel (or the entire page) on a timed basis. The Timer control has one important property:

IntervalThe amount of time, in milliseconds, between Tick events. The default value is 60,000 (1 minute).

The Timer control raises a Tick event every so many milliseconds, depending on the value of its Interval property.

If you don’t associate the Timer control with an UpdatePanel, the Timer posts the entire page back to the server performing a normal postback. For example, the page in Listing 38.22 posts the entire page back to the server every 2 seconds.

Listing 38.22. TimerPage.aspx

images

A more typical use of the Timer control is to refresh an UpdatePanel control’s content on a timed basis. For example, the page in Listing 38.23 displays a random quotation every 2 seconds (see Figure 38.14).

Figure 38.14. Refreshing the control content using Timer control.

image

Listing 38.23. TimerQuote.aspx

images

images

The Timer control in Listing 38.23 is configured as a trigger for the UpdatePanel control. When the Timer raises its Tick event, the UpdatePanel control refreshes its content by performing an asynchronous postback and grabbing a new quotation to display.

The final example of the Timer control is contained in Listing 38.24. In this example, a Timer control refreshes a discussion forum’s messages every 5 seconds. If you leave your browser window open, you see new messages as they are posted by other members of the forum (see Figure 38.15).

Figure 38.15. Database messages being updated asynchronously.

image

Listing 38.24. TimerMessages.aspx

images

images

The page in Listing 38.24 contains a ListView that gets refreshed every 5 seconds. Be aware that every person who has this page open in a browser will cause a database call to be made every 5 seconds. This data is an excellent candidate for caching.

Using the UpdateProgress Control

The last control that we need to examine in this chapter is the UpdateProgress control. This control enables you to display a progress indicator while an UpdatePanel is updating its content.

During a normal postback, the browser displays its progress in downloading new content by spinning an icon or displaying a progress bar. During an asynchronous postback, on the other hand, there is no visual indication of progress. You can use the UpdateProgress control to give the users some sense that something is happening during an asynchronous postback.

Note

In the next chapter, we examine an alternative method of displaying UpdatePanel progress. You learn how to use the UpdatePanelAnimation control to display an animation while an UpdatePanel's content is refreshed.

The page in Listing 38.25 illustrates how to use the UpdateProgress control. If you click the button, an animation spins while the asynchronous postback is performed (see Figure 38.16).

Figure 38.16. Viewing a spinning asynchronous progress indicator.

image

Listing 38.25. ShowUpdateProgress.aspx

images

images

When you click the button in Listing 38.25, the response is delayed for 5 seconds so you have a chance to see the progress indicator. The delay simulates a network delay.

Note

Several websites enable you to generate fancy animator progress indicator icons. Here is the address to one of my favorites:

http://www.ajaxload.info

The UpdateProgress control supports the following three properties:

AssociatedUpdatePanelIDThe UpdateProgress control displays progress for this UpdatePanel control.

DisplayAfterThe amount of time, in milliseconds, before the UpdateProgress control displays content. The default is 500 milliseconds (half a second).

DynamicLayoutWhen this property is set to true (the default), the UpdateProgress control is initially hidden with the Cascading Style Sheet (CSS) attribute display:none. When this property is set to false, the UpdateProgress control is hidden with the CSS attribute visibility:hidden.

Summary

In this chapter, you learned how to use the primary server-side ASP.NET AJAX control: UpdatePanel. The bulk of this chapter was devoted to discussing the different features of this control. You learned how to specify triggers for an UpdatePanel. You also learned about how the UpdatePanel control participates in a page’s server-side and client-side page execution life cycle. We also examined how you can handle errors gracefully when using the UpdatePanel control.

In the final parts of this chapter, you learned how to use two controls that support the UpdatePanel control. First, you learned how to use the Timer control to refresh an UpdatePanel on a timed basis. Second, you learned how to use the UpdateProgress control to give the user something to watch during an UpdatePanel control’s asynchronous postback.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset