Periodically Updating the Screen and Web Page Title with ASP.NET AJAXBy Scott Mitchell
Consider the following scenario: you are building a website that serves as a front-end for a work item database. The database contains tasks assigned to an employee; throughout the course of the day new tasks may be assigned to an employee by other workers, by automated processes, or by other means. When an employee logs onto the site he sees a hyperlink that lists the number of open work items in the upper left corner of every page, and clicking that link takes him to a page that lists the open work items in his queue. After completing a work item he closes it, which removes it from his list of open work items. In a typical web application the number of open work items in the upper left corner would only be refreshed when the user performed a postback, manually refreshed the page, or visited a new page. Wouldn't it be nice if that count of open work items would interactively update as new work items assigned to the user entered the queue?
An Look at the Work Item Website and Pre-AJAX "Open Work Items" Display Area
The download available at the end of this article includes a demo illustrating the concepts touched upon in this article. The demo is a very simple data-driven web application that is designed to allow users to log on, see their open work items, and, once a work item has been completed, mark it as such. The application uses ASP.NET's Membership system to support user accounts; specifically, the
SqlMembershipProviderprovider is used and the user accounts are stored in the
ASPNETDB.mdfdatabase in the
ASPNETDB.mdf database also contains the
WorkItems table, which has a record for each work item in the system. As the
following schema shows, each
WorkItems record has a unique identifier (
WorkItemID), a description (
is associated with a particular user (
UserId), and has the date and time the work item was added and completed (if it has been completed).
|Primary key, IDENTITY|
|Foreign key to |
|The date/time the record was added to to the table|
|Can be |
The web application consists of three pages:
- Default.aspx - the site's home page
- Login.aspx - the login page
- WorkItems.aspx - displays the currently logged on user's list of open and completed work items
WorkItems.aspxpage, shown in the screen shot below, had a button for adding one to five new work items along with two GridView controls. The top GridView displays open work items (those whose
NULL) and completed work items (those whose
DateCompletedvalue is not
NULL). The open work items GridView includes a CLOSE LinkButton in each row that, when clicked, closes the work item by setting the corresponding record's
DateCompletedvalue to the current date and time.
The three ASP.NET pages in the website all use the same master page,
Site.master, which defines the common look and feel - the text
"Updating the Screen and Title Demo" at the top of the page, the "Home" and "Your Work Items" links along the left column, and the "Welcome back, Username"
message in the upper right. There's also an area in the upper left corner that lists how many open work items there are for the current user. It's circled
in the above screen shot, and reads: "3 open work items." This text is actually a link, clicking it whisks the user to the
Moreover, this text in is the master page and therefore appears on every content page, including
Default.aspx and other, future pages.
Imagine that a user visits
Default.aspx at 3:00 PM and she has three open work items. She will see the message, "3 open work items" in
the upper left corner of the screen. Now, imagine that she minimizes her browser and starts working on non-work item tasks and that, during that time,
two new work items are added to her queue. When she brings her browser back to the foreground the page has not been updated, it still reports that there
are three open work items. Granted, if she manually refreshes the screen at this time she'll see that there are now really five open work items, but she
must remember to do this. Some web applications "force" a period refresh by adding a
element to the page to force a refresh every so often, but this approach can disorient users and can be very frustrating in pages where
the user may be busy entering information in textboxes or working with other user input elements on the page, only to have that information lost when
the page is automatically refreshed.
A High-Level Overview of How the Screen and Title is Periodically Updated
Before we delve into the details of updating the screen and page title with the currently logged on user's open work item count, let's first take a high-level look at the solution. We need some way for the page to contact the server and ask, "How many work items are open for the currently logged on user?", and we need this question to be asked periodically, say once every 30 seconds. Furthermore, when getting the answer to this question we need to display it in the text in the upper left corner and update the page's title.
Last week's article, Retrieving Server-Side Data Using Web Services, showed how
the server and make it accessible from client-side script by decorating it with the
ScriptService attribute. Moreover, you can create a
setInterval(code, timeout) that executes code every timeout number of
milliseconds. Therefore, we can use this function to call the Web service every 30 seconds (or whatever duration you decide on). For more information on
this function (as well as information on a related function,
programmatically reference an HTML element and then tweak its display via its
innerHTML property. A page's title can be read and modified via
Creating a Script-Enabled Web Service for Returning the Number of Open Work Items
The first step is to create a script-enabled Web service that returns the number of open work items for the currently logged on user. Create a new Web service, decorate it with the
ScriptServiceattribute, and then add the following method:
When the client application calls the Web service it passes along its cookies. Because this website uses forms-based authentication, when a user logs on
to the site an authentication ticket is added to the cookies collection so that the user can be identified on subsequent requests.
Consequently, we can determine the user calling this Web service (if they have already logged on) by the authentication ticket in their cookies.
Of course, we don't need to write any code to inspect a user's authentication ticket; instead, this all happens behind the scenes by the ASP.NET engine.
We can get information about the currently logged on user by simply calling
Membership.GetUser() or from the
The above Web service method starts by calling the
Membership.GetUser() method. If this method returns
Nothing then the person making
this Web service call is anonymous. In such a case the method returns a value of -1. But if the user is authenticated then their
UserId value is
grabbed from the
ProviderUserKey property and is then used in the SQL query that returns the number of
open work items. This count is returned.
Site.master.) The ScriptManager control's declarative markup follows:
Calling the Script-Enabled Web Service and Updating the Screen and Title
UpdateOpenWorkItemCount, calls the
GetOpenWorkOrdersWeb service asynchronously and indicates that the
GetOpenWorkOrdersOnFailedfunctions are to be called on success or on failure, respectively.
The text - "3 open work items", or whatever the number may be - is displayed by a HyperLink control on the master page named
that, when clicked, sends the user to the
The HyperLink control renders an anchor element (
<a>), which can be programmatically referenced via the DOM and its
set to change the link's text. The
GetOpenWorkOrdersOnSuccess function updates this link text along with the page's title. These areas are
only updated if the value returned from the Web service is greater than or equal to zero. (Recall that if the Web service is called by an anonymous user it returns
a value of -1. In that case we do not want to update the screen or title.) The code for the
GetOpenWorkOrdersOnSuccess function follows:
Updating the Display On Page Load and Every 30 Seconds After That
The last piece of the puzzle is having the
UpdateOpenWorkItemCountfunction, which calls the Web service and updates the display, invoked on page load and every 30 seconds (or whatever) thereafter. This is accomplished by creating a
UpdateOpenWorkItemCountfunction immediately and then using
setIntervalso that it's called after every 30 second interval.
That's all there is to it! To change the frequency with which the
UpdateOpenWorkItemCount function is called, change the
function's second input parameter from 30000 (30 seconds) to whatever value you prefer.
The Screen and Title Updates In Action!
To see the screen and page title updates in action download the web application from the end of this article. Open it in Visual Studio and launch the website. Open two browser instances and log into the site. In one browser instance visit
Default.aspx, on the second go to
WorkItems.aspx. At this point you should see the number of open work items in the upper left corner. For example, in the screen shot below you can see that there are three open work items.
Also note that the number of open work items is shown in the page's title. This appears in the top window bar, the tab, and the task bar.
From the second browser instance (
WorkItems.aspx), close two work items. Return to the first browser instance (
Do not refresh the page, but wait. Within 30 seconds you should see the text in the upper left corner (and in the page's title) change to reflect that
there is now only one open work item. Neat!