The key technique in an Ajax web application is partial refreshes.
With partial refreshes, the entire page doesn't need to be posted back
and refreshed in the browser. Instead, when something happens the web
page asks the web server for more information. The request takes place
in the background, so the web page remains responsive. (It's up to you
whether you use some sort of progress indicator if you think the request
might take a noticeable amount of time.) When the web page receives the
response, it updates just the changed portion of the page, as shown in Figure 1.
ASP.NET includes a handy
control that lets you take an ordinary page with server-side logic and
make sure it refreshes itself in flicker-free Ajax style using partial
updates. This control is the UpdatePanel.
The basic idea is that you
divide your web page into one or more distinct regions, each of which is
wrapped inside an invisible UpdatePanel. When an event occurs in a
control that's located inside an UpdatePanel, and this event would
normally trigger a full-page postback, the UpdatePanel intercepts the
event and performs an asynchronous callback instead. Here's an example
of how it happens:
The user clicks a button inside an UpdatePanel.
The
UpdatePanel intercepts the client-side click. Now, ASP.NET AJAX
performs a callback to the server instead of a full-page postback.
On
the server, your normal page life cycle executes, with all the usual
events. Finally, the page is rendered to HTML and returned to the
browser.
ASP.NET
AJAX receives HTML content for every UpdatePanel on the page. The
client-side script code then updates the page, replacing the existing
HTML that's in each panel with the new content. (If a change has
occurred to content that's not inside an UpdatePanel, it's ignored.)
NOTE
If you access a page that
uses the UpdatePanel with a browser that doesn't support Ajax or
doesn't have JavaScript switched on, it uses normal postbacks instead of
partial updates. However, everything else still works correctly.
1. A Simple UpdatePanel Test
To try out the UpdatePanel, it makes sense to build a simple test page.
The following example (Figure 2)
uses a simple page that includes two ingredients: an animated GIF
image, and a shaded box that shows the current time and includes a
Refresh Time button. When you click the Refresh Time button, the page
grabs the current time from the web server and updates the label.
However, the refresh process uses a partial update. As a result, the
page won't flicker when it takes place. The animated GIF helps
illustrate the point—even as you click the button to refresh the label,
the lamp continues bubbling without a pause or hiccup.
Building this page is easy.
First, you need to add the ScriptManager control to the page. Like all
controls that use ASP.NET AJAX, the UpdatePanel works in conjunction
with the ScriptManager. If you don't have it in your page, the
UpdatePanel won't work (and you'll receive an exception when you run the
page). Furthermore, the ScriptManager needs to appear before the
UpdatePanel, because the rendered page must have the JavaScript script
block in place before the UpdatePanel can use it. It's a good idea to
always place the ScriptManager at the top of the <form> section of
the page.
Next, you need to add the
content to the page. The animated GIF is fairly straightforward—you can
use an ordinary <img> element to show it. However, the label and
button require a bit more effort. To refresh the label using a partial
refresh, you need to wrap it in an UpdatePanel. So start by adding an
UpdatePanel to your page, and then drag and drop the button and label
inside.
The UpdatePanel has one
role in life—to serve as a container for content that you want to
refresh asynchronously. Interestingly enough, the UpdatePanel doesn't
derive from Panel. Instead, it derives directly from Control. This
design causes a few quirks that you should take into account.
First, the UpdatePanel
is invisible. Unlike the standard ASP.NET Panel, an UpdatePanel doesn't
support style settings. If you want to display a border around your
UpdatePanel or change the background color, you'll need to place an
ordinary Panel (or just a plain <div> tag) in your UpdatePanel.
Here's how it's done in the example shown in Figure 2:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div style="background-color:LightYellow;padding: 20px">
<asp:Label ID="lblTime" runat="server" Font-Bold="True"></asp:Label>
<br />
<br />
<asp:Button ID="cmdRefreshTime" runat="server"
Text="Refresh Time" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
This markup reveals
another difference between the UpdatePanel and an ordinary Panel—the
UpdatePanel uses a template. All the controls you add to an UpdatePanel
are placed in an element named <ContentTemplate>. When the
UpdatePanel renders itself, it copies the content from the
ContentTemplate into the page. This seems like a fairly unimportant
low-level detail, but it does have one important side effect. If you
want to use code to dynamically add controls to an UpdatePanel, you
can't use the UpdatePanel.Controls collection. Instead, you need to add
new controls to the UpdatePanels.ContentTemplateContainer.Controls
collection.
Now that you have the
controls you need, you're ready to add the code. This part is easy—when
the button is clicked, you simply react to the Click event and update
the label:
Protected Sub cmdRefreshTime_Click(ByVal sender As Object, _
ByVal e As EventArgs) Handles cmdRefreshTime.Click
lblTime.Text = DateTime.Now.ToLongTimeString()
End Sub
Remarkably, that's all you
need to do to complete this example. Now, when you click the Refresh
Time button, the label will refresh without a full postback and without
any flicker.
So how does it all work? Here's a blow-by-blow analysis of what's taking place:
When
rendering the HTML, the UpdatePanel looks at its contents. It notices
that it contains one control that's able to trigger a postback—the
button. It adds some JavaScript code that will intercept the button's
click event on the client and use a JavaScript routine to handle it.
When you click the Refresh Time button, you trigger the JavaScript routine.
The
JavaScript routine doesn't perform a full-page postback. Instead, it
sends a background request to the web server. This request is
asynchronous, which means your page remains responsive while the request
is under way.
NOTE
Because the
UpdatePanel uses asynchronous requests, it's possible to click the
Refresh Time button several times before the result is returned and the
time is updated. In this case, the response from the first few requests
is ignored, and the response from the last request is used. (It's
similar to what happens if you refresh a posted-back page several times
before it's finished being processed on the server.)
The background request is processed in exactly
the same way as a normal postback. All the data from all the web
controls is sent back to the web server, along with the view state
information and any cookies. On the web server, the page life cycle is
the same—first the Page.Load event fires, followed by the event that
triggered the postback (in this case, Button.Click). If you're using
data source controls like SqlDataSource, all the normal querying and
data binding takes place. The final page is then rendered to HTML and
sent back to the page.
When
the browser receives the rendered HTML for the page, it updates the
current view state and grabs any cookies that were returned.
The
JavaScript routine then replaces a portion of the HTML on the page—just
the portion that you wrapped in the UpdatePanel. The rest of the HTML
for the page is simply discarded. In the current example, that means the
HTML with the animated GIF is tossed out. (This really has no effect,
because this part of the HTML is exactly the same in the new response as
it was originally. However, it's important to understand that if you
modify this part of your page on the web server, you won't see the
results of your change in the web browser, because that area of the page
isn't being updated.)
The most impressive aspect of
the UpdatePanel control is that it allows your web page to behave in the
same way it would if you weren't using any Ajax techniques. There is a
bit of a price to pay for this convenience—namely, the request might
take a little longer than necessary because of all the extra work that's
taking place. In a more streamlined do-it-yourself approach, you'd
simply ask the web server for exactly what you need. In this example,
that means you'd simply ask for the current time, rather than an entire
HTML document.
However, in most
scenarios the UpdatePanel's more long-winded approach doesn't introduce
any noticeable delay. Even better, it gives you the ability to deal with
much more complex scenarios—for example, when you're modifying a
section of a web page much more dramatically.
NOTE
When you use the
UpdatePanel, you don't reduce the amount of bandwidth being used or the
time taken to receive the response from the server, because the entire
page is still sent. The only difference is that the page is updated
without a distracting flicker. Small as that advantage seems, it can
make a major difference in how your web page "feels" to the person using
it.