Vous êtes sur la page 1sur 47

ASP.

NET AJAX
for Developers

Information in this document is subject to change without notice. The example companies,
organizations, products, people, and events depicted herein are fictitious. No association with
any real company, organization, product, person or event is intended or should be inferred.
Complying with all applicable copyright laws is the responsibility of the user. Without limiting
the rights under copyright, no part of this document may be reproduced, stored in or
introduced into a retrieval system, or transmitted in any form or by any means (electronic,
mechanical, photocopying, recording, or otherwise), or for any purpose, without the express
written permission of Microsoft Corporation.

Microsoft may have patents, patent applications, trademarked, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you
any license to these patents, trademarks, copyrights, or other intellectual property.

© 2007 Microsoft Corporation. All rights reserved.

Microsoft, MS-DOS, MS, Windows, Windows NT, MSDN, Active Directory, BizTalk, SQL Server,
SharePoint, Outlook, PowerPoint, FrontPage, Visual Basic, Visual C++, Visual J++, Visual
InterDev, Visual SourceSafe, Visual C#, Visual J#, and Visual Studio are either registered
trademarks or trademarks of Microsoft Corporation in the U.S.A. and/or other countries.

Other product and company names herein may be the trademarks of their respective owners.
Table of Contents

1.0 Introducing ASP.NET AJAX ................................................................ 3


1.1 A Brief History of AJAX ................................................................. 3
1.2 How AJAX Works ......................................................................... 4
1.3 ASP.NET AJAX ............................................................................ 7
1.4 Feature Factoring ..................................................................... 10
2.0 The ASP.NET 2.0 AJAX Extensions ..................................................... 12
2.1 Core AJAX Server Controls ........................................................... 12
2.1.1 ScriptManager and ScriptManagerProxy...................................... 13
2.1.2 UpdatePanel...................................................................... 15
2.1.3 UpdateProgress .................................................................. 18
2.2 ASP.NET AJAX Control Toolkit Server Controls ................................... 19
2.3 ASP.NET AJAX Futures CTP Server Controls ....................................... 22
2.4 Web Services ........................................................................... 23
2.4.1 Web Service Extensions......................................................... 25
2.4.2 The ScriptMethod Attribute.................................................... 27
2.5 Page Methods .......................................................................... 27
2.6 JSON ..................................................................................... 28
2.7 Built-In Web Services ................................................................. 30
2.7.1 AuthenticationService .......................................................... 30
2.7.2 ProfileService .................................................................... 31
3.0 The Microsoft AJAX Library ............................................................. 33
3.1 JavaScript Base Type Extensions.................................................... 34
3.2 Global Functions and Variables ..................................................... 34
3.3 JavaScript Type System (Adding OOP to JavaScript) ............................ 35
3.4 Script Core Library .................................................................... 38
3.5 Base Class Library ..................................................................... 39
3.6 PageRequestManager ................................................................. 41
3.7 HTML Controls.......................................................................... 42
3.8 xml-script ............................................................................... 44
4.0 Summary ................................................................................... 47
1.0 Introducing ASP.NET AJAX
ASP.NET AJAX is a free framework that simplifies the development of AJAX-enabled
Web pages and Web applications. It is both a set of server-side extensions to Microsoft
ASP.NET 2.0 and a client-side library written in JavaScript that is browser-independent
and agnostic to server platforms. Indeed, the client half of ASP.NET AJAX can be used
with PHP, ColdFusion, and other non-Microsoft platforms almost as easily as it is used
with ASP.NET. Because ASP.NET AJAX is 100% browser-independent, pages built with it
work not only in Microsoft Internet Explorer, but in Mozilla Firefox, Apple Safari, and
other modern browsers. And ASP.NET AJAX bears the distinction of being the only
AJAX framework created by Microsoft—in fact, by the same team that produced
ASP.NET.

ASP.NET AJAX abstracts the mechanics of AJAX so developers can build AJAX-enabled
applications without having to become experts in JavaScript, XML-HTTP, and other
technologies that make up AJAX itself. For example, ASP.NET AJAX includes an
UpdatePanel control that enables selected regions of a Web page to be updated via
AJAX. Simply adding an UpdatePanel control to a page can often replace tens of hours
of tedious coding involving JavaScript, browser Document Object Models (DOMs), and
XmlHttpRequest objects. Similar abstractions reduce the complexity of other tasks—
adding animations, popup panels, drag-and-drop support, and more—to little more
than declaring controls in a Web page.

This document contains a technical overview of ASP.NET AJAX and is specifically


intended to help developers understand, evaluate, and get started using ASP.NET
AJAX. Additional information about ASP.NET AJAX, as well as instructions for
downloading and installing it, can be found at http://ajax.asp.net/.

1.1 A Brief History of AJAX


The term “AJAX” was coined in February 2005 by Jesse James Garrett in a seminal
paper titled “Ajax: A New Approach to Web Applications.” The paper identifies the
following technologies as the constituent components of AJAX:

• Standards-based presentation using XHTML and CSS


• Dynamic display and interaction using the DOM
• Data interchange and manipulation using XML and XSLT
• Asynchronous data retrieval using XMLHttpRequest objects
• JavaScript binding everything together

AJAX stands for Asynchronous JavaScript and XML. “Asynchronous” alludes to the
asynchronous calls (or “callbacks”) that AJAX browser clients make to Web servers to
submit (and often to retrieve) data. Callbacks are launched by JavaScript executing in
the browser, and when a callback completes, JavaScript is used to process the results.
The chief benefit to performing callbacks asynchronously is that it frees the browser
to execute code and continue responding to user input while waiting for callbacks to
complete.

The “XML” in “Asynchronous JavaScript and XML” alludes to the protocol used by
asynchronous callbacks (XML-HTTP) and to the browser object used to execute XML-
HTTP requests (XmlHttpRequest). AJAX applications sometimes use XML to serialize
data transmitted over the wire, but inceasingly, JSON—short for JavaScript Object
Notation—is the serialization format of choice. JSON is more compact than XML, is
more readable to the human eye, and typically requires less time and processing
power to decode. For these reasons, it’s the native serialization format employed by
ASP.NET AJAX. You can read all about JSON at http://www.json.org/.

In the words of the creator of the term AJAX, “Ajax isn’t a technology. It’s really
several technologies, each flourishing in its own right, coming together in powerful
new ways.” Indeed, the two technologies that form the foundation for all AJAX
applications—JavaScript and XmlHttpRequest—predate AJAX by many years.

JavaScript debuted in 1995 in a beta release of Netscape Navigator 2.0. Originally


titled “LiveScript,” its name changed to JavaScript before year’s end. Shortly
thereafter, Microsoft added support to Internet Explorer for an almost identical
scripting language named JScript. JavaScript was submitted to the European standards
body ECMA (European Computer Manufacturers’ Association) as ECMAScript in 1996 and
today is both an ECMA and ISO standard.

Whereas Netscape invented JavaScript, Microsoft invented the XmlHttpRequest


object. XmlHttpRequest was created to enrich the user interface of Outlook Web
Access (OWA) and was originally implemented as an ActiveX object in Internet Explorer
5.0. (OWA was, in fact, the first AJAX application, although it wasn’t called that
because the term “AJAX” had yet to be invented.) Other browser vendors followed
suit, and today virtually all modern browsers support XmlHttpRequest in one form or
another. Rather than implement XmlHttpRequest as an ActiveX object, third-party
browsers implement it as a native browser object. For consistency with other browsers
and to avoid some of the security concerns involving ActiveX controls, Microsoft
included a native XmlHttpRequest object in Internet Explorer 7. XmlHttpRequest is
currently in the process of being standardized by the World Wide Web Consortium
(W3C). For the latest information on the standardization process, visit
http://www.w3.org/TR/XMLHttpRequest/.

Today AJAX is employed by numerous Web applications to make browsing the Web a
richer and more pleasing experience. Examples or popular Web applications that use
AJAX include Windows Live Local, Outlook Web Access, Gmail, Google Suggests, and
Google Earth. In all likelihood, the popularity of AJAX will only increase in coming
years and drive the demand for AJAX frameworks such as ASP.NET AJAX.

1.2 How AJAX Works


A classic use for AJAX in Web applications is to improve the user experience by
replacing postbacks with asynchronous callbacks. Traditional Web applications use
form submission events transmitted via HTTP POSTs—“postbacks” in ASP.NET
parlance—to execute round trips to the server. Postbacks suffer two significant
drawbacks:

• When a postback occurs, the browser discards the HTML it’s holding and
redraws the page using the HTML returned in the HTTP response. Consequently,
the entire page “flashes” even if only a fraction of the page actually needed to
be redrawn.
• When a postback occurs, all of the form input on the page—including ASP.NET
view state and other data stored in hidden input fields—is transmitted to the
server, even if only a fraction of that input is actually used.

Replacing postbacks with asynchronous XML-HTTP callbacks offers the following


benefits:

• The browser no longer discards the HTML it’s holding, eliminating the flashing
and vastly improving the user experience.

• Rather than transmit all form input to the server, an asychronous callback can
transmit just the input that’s needed, leading to better and more efficient
bandwidth utilization.

Figure 1-1 demonstrates how replacing postbacks with callbacks improves the user
experience. The browser first submits a conventional HTTP GET request to fetch HTML
content from a Web server. The browser renders the content to display the Web page.
When the user clicks a button on the page, what would normally be a postback in an
ASP.NET page is instead an asynchronous callback thanks to a bit of JavaScript wired
to the button. The callback travels to the server in the form of an asynchronous XML-
HTTP request. Significantly, the browser doesn’t discard the HTML it’s displaying, so
until the callback completes, the page remains unchanged in the browser.

Figure 1-1: Using AJAX to perform partial-page rendering


When the callback completes, JavaScript code downloaded to the browser retrieves
the results of the call and uses the browser DOM to update the content on the page. In
this example, the JavaScript updates an image on the page by changing an <img> tag’s
src attribute. This scenario, in which an XML-HTTP request travels back to the server
and JavaScript on the client updates what the user sees using the results of the call, is
commonly known as partial-page rendering. The unsightly flashing that characterizes
many Web pages is eliminated, and in some implementations, the volume of data
traveling over the wire is greatly reduced.

The first step in launching an asynchronous XML-HTTP request is to instantiate an


XmlHttpRequest object. The following JavaScript code does just that, and it employs a
multifaceted “discovery” strategy for the XmlHttpRequest object that works in
virtually all modern browsers:

var xhr = null;

if (window.XMLHttpRequest)
{
xhr = new XMLHttpRequest(); // IE 7, Firefox, etc.
}
else // Older IE browsers
{
try
{
xhr = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (ex)
{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
}

The next step is to launch the callback itself. That’s accomplished by opening the
XmlHttpRequest object (and in the process providing key information such as the URL
targeted by the XML-HTTP request) and calling its send method. The “true” passed in
the third parameter specifies that the request should be submitted asynchronously
rather than synchronously:

xhr.open ('GET', 'AjaxDemo.aspx', true);


xhr.onreadystatechange = checkForCompletion;
xhr.send ();

...

function checkForCompletion()
{
if (xhr.readyState == 4 && xhr.status == 200)
{
window.alert(xhr.responseText);
}
}

Because the call is asynchronous, send returns immediately. In this example, the
checkForCompletion function is called each time the XmlHttpRequest object’s ready
state changes. A readyState property equal to 4 indicates that the asynchronous
request has completed, and a status code of 200 indicates it completed successfully.
This example uses window.alert to display the response returned by the callback,
which is accessed through the XmlHttpRequest object’s responseText property. (If the
response contains an XML document rather than raw text, responseXML can be used
instead.) In real life, JavaScript code of greater complexity is typically provided to do
something more tangible with the response—for example, to update content on the
page.

As an added complication when AJAX is hand-coded, it is the developer’s responsibility


to serialize and deserialize data passed over the wire in the request and response.
Passing simple data types such as strings is easy; passing complex data such as
instances of custom data types is commensurately more difficult.

Writing AJAX code without the benefit of an AJAX framework can be tedious and time-
consuming due to differences between browsers and the need to write JavaScript code
to process the results of XML-HTTP requests. AJAX frameworks such as ASP.NET AJAX
simplify the development process by encapsulating and abstracting key aspects of
AJAX itself, and even by abstracting the differences between browsers.

1.3 ASP.NET AJAX


AJAX frameworks represent the second step in the evolution of AJAX (the first step
being the invention of AJAX itself) and provide much-needed abstractions that enable
AJAX Web pages to be built in minutes rather than hours or days. ASP.NET AJAX is the
AJAX framework from Microsoft. It is divided into two distinctly different yet
interrelated halves:

• The ASP.NET 2.0 AJAX Extensions, which reside on Web servers


• The Microsoft AJAX Library, which resides in browser clients

The ASP.NET 2.0 AJAX Extensions are the server half of ASP.NET AJAX. A schematic
appears in Figure 1-2. The box labeled “AJAX Server Controls” represents controls such
as UpdatePanel and UpdateProgress, which provide easy-to-use wrappers around AJAX.
The application services bridge is a set of Web services that expose key ASP.NET 2.0
services such as membership and profiles to browser clients. The asynchronous
communications layer permits ASMX Web methods and special ASPX methods known as
page methods to serve as endpoints for AJAX callbacks. It also enhances ASP.NET 2.0
with support for JSON serialization and deserialization. The ASP.NET 2.0 AJAX
Extensions are described more fully in Section 2.0.

Figure 1-2: The ASP.NET 2.0 AJAX Extensions


The Microsoft AJAX Library is the client half of ASP.NET AJAX. Its structure is shown in
Figure 1-3. The Base Class Library and Script Core Library are JavaScript libraries that
make JavaScript an easier and more productive language in which to work. They can
be leveraged directly with hand-written JavaScript code, but more importantly, they
can be (and are) leveraged by code and markup emitted by AJAX server controls. The
asynchronous communications layer provides support for network communications
(including asynchronous XML-HTTP requests) and JSON serialization and
deserialization. The browser compatibility layer enables ASP.NET AJAX applications to
work in a wide variety of browser types. The Microsoft AJAX Library is described more
fully in Section 3.0.

Figure 1-3: The Microsoft AJAX Library


Here are four key points to keep in mind regarding ASP.NET AJAX:

• AJAX server controls make it extremely easy to add AJAX support to ASP.NET
Web pages. Simply declare a control on the page and the control does the rest.

• AJAX server controls require ASP.NET on the server. They emit code (and
sometimes markup) that leverages the Microsoft AJAX Library on the client.

• The Microsoft AJAX Library, which is browser-independent and written entirely


in JavaScript, is the engine that drives ASP.NET AJAX. It can be leveraged by
declaring AJAX server controls on a page, or by writing JavaScript code that
uses the Microsoft AJAX Library directly.

• The Microsoft AJAX Library is independent of server platforms; it doesn’t


require ASP.NET or any other platform, for that matter. You could leverage it
from PHP or other platforms simply by embedding JavaScript in your pages. Or
you could write server-side PHP wrappers that emit code and markup just like
ASP.NET 2.0 AJAX Extensions server controls.
1.4 Feature Factoring
ASP.NET AJAX can be downloaded from the ASP.NET AJAX downloads page at
http://ajax.asp.net/default.aspx?tabid=47&subtabid=471. That page features four
separate downloads:

• ASP.NET AJAX 1.0


• ASP.NET AJAX Control Toolkit
• ASP.NET AJAX Futures CTP
• Microsoft AJAX Library

The ASP.NET AJAX 1.0 download contains the core features of the platform, including
the UpdatePanel server control and the browser compatibility layer and asynchronous
communications layer on the client. These features are fully tested and fully
supported by Microsoft.

The ASP.NET AJAX Control Toolkit adds several additional server controls to the
package as well as a software development kit (SDK) for developing controls of your
own. The ASP.NET AJAX Control Toolkit is a shared-source, community-supported
project. It is fully tested, vetted by the community, and considered robust enough for
use on production servers. It’s hosted at CodePlex (http://www.codeplex.com/) and is
constantly being updated with new controls and code samples.

The ASP.NET AJAX Futures CTP further expands the feature set and provides a
mechanism for Microsoft to deliver new features and collect feedback on those
features. CTP stands for “Community Technology Preview” and is the term used to
describe features that are still under development. Conservative shops that prefer to
use only fully tested, fully supported features of the platform can do so by installing
only the core ASP.NET AJAX download (and optionally the control toolkit). More agile
shops that want to leverage ASP.NET AJAX to the fullest can install the Futures CTP
and enjoy access to a wider range of features. Figure 1-4 documents the division of
features between core and CTP.

Figure 1-4: ASP.NET AJAX feature matrix

Server
ASP.NET AJAX
Feature ASP.NET AJAX January 2007
Futures CTP
Asynchronous client-to-server networking ●
ScriptManager and ScriptManagerProxy controls ●
UpdatePanel control ●
UpdateProgress control ●
Timer control ●
Application services bridge ●
Page methods ●
DragOverlayExtender control ●
ProfileService control ●
Client
ASP.NET AJAX
Feature ASP.NET AJAX January 2007
Futures CTP
JavaScript type extensions ●
JavaScript type system ●
JSON serialization and deserialization ●
Client-side application services bridge ●
Calling Web services from JavaScript ●
Debugging aids ●
HTML controls (Button, CheckBox, Label, etc.) ●
Data controls (ListView, ItemView, etc.) ●
Validation controls ●
Drag-and-drop support ●
Animation support ●
xml-script support ●

The fourth download—the Microsoft AJAX Library—contains the JavaScript files that
make up the Microsoft AJAX Library. Developers building applications for non-ASP.NET
platforms can use these files to enjoy all the benefits of ASP.NET AJAX in browser
clients—without the need for ASP.NET on the server.
2.0 The ASP.NET 2.0 AJAX Extensions
The ASP.NET 2.0 AJAX Extensions extend ASP.NET 2.0 with new controls, features, and
capabilities, including the ability to use ASMX Web methods and ASPX page methods as
endpoints for asynchronous XML-HTTP requests and support for JSON serialization and
deserialization. They also include built-in Web services that enable the ASP.NET 2.0
membership and profile services to be accessed by JavaScript clients.

Core features of the ASP.NET 2.0 AJAX Extensions are contained in the assembly
System.Web.Extensions.dll, which is added to the Global Assembly Cache (GAC) when
ASP.NET AJAX is installed. The ASP.NET AJAX Control Toolkit is packaged in a separate
assembly named AjaxControlToolkit.dll, while the Futures CTP lives in
Microsoft.Web.Preview.dll. AjaxControlToolkit.dll and Microsoft.Web.Preview.dll are
not installed in the GAC; instead, they’re privately deployed in the Bin subdirectory.

The sections that follow introduce the ASP.NET 2.0 AJAX Extensions and offer a guided
tour of its features.

2.1 Core AJAX Server Controls


The most visible component of the ASP.NET 2.0 AJAX Extensions is the family of
controls known as the AJAX server controls. These controls abstract AJAX and greatly
simplify the process of building AJAX-enabled Web pages.

The AJAX server controls supplement the server controls built into ASP.NET (TextBox,
Panel, TreeView, and so on) and conform to the same programming model and usage
patterns. In Visual Studio, AJAX server controls can be dragged from the Toolbox and
dropped onto a page to add AJAX capabilities to that page. Figure 2-1 lists the core
AJAX server controls included in ASP.NET AJAX 1.0.

Figure 2-1: Core AJAX server controls

Control Description
ScriptManager Enables ASP.NET AJAX to be used in a Web page.
ScriptManagerProxy Enables content pages to add script references and
service references to a ScriptManager control declared in
a master page.
UpdatePanel Implements partial-page rendering in a Web page.
UpdateProgress Displays a custom user interface (UI) while updates are
pending in UpdatePanel controls.
Timer Implements a programmable callback timer.

The following sections provide a brief overview of these controls. The goal isn’t to
provide an exhaustive reference, but to provide helpful information regarding the
controls’ capabilities and syntactical help using them.
2.1.1 ScriptManager and ScriptManagerProxy
Every ASP.NET AJAX page begins with a ScriptManager control. The ScriptManager
control’s primary duties include:

• Downloading Microsoft AJAX Library JavaScript files to the browser if they


haven’t been downloaded already

• Declaring service references that enable Web services to be called directly


from the browser through JavaScript proxies

• Providing control over error handling—what happens when an exception is


thrown on the server during an asynchronous callback

ScriptManager controls also provide script registration methods (so custom controls
that emit JavaScript can be compatible with UpdatePanel controls), allow localization
features to be enabled and disabled, control whether the debug or release version of
the Microsoft AJAX Library is downloaded, and more.

A page that uses ASP.NET AJAX must contain one—and only one—ScriptManager
control. The declaration can be as simple as this:

<asp:ScriptManager ID="ScriptManager1" runat="server" />

Figure 2-2 offers a more comprehensive look at the ScriptManager schema. The
<Services> element declares Web service references, enabling those Web services to
be called through JavaScript proxies (Section 2.4). The <Scripts> element enables a
page to download JavaScript files that aren’t downloaded by default. For example,
the following ScriptManager declaration downloads PreviewScript.js, which contains
many of the Microsoft AJAX Library features found in the ASP.NET AJAX Futures CTP,
as well as a custom JavaScript file named UIMap.js:

<asp:ScriptManager ID="ScriptManager1" runat="server">


<Scripts>
<asp:ScriptReference Name="PreviewScript.js"
Assembly="System.Web.Preview" />
<asp:ScriptReference Path="~/Scripts/UIMap.js" />
</Scripts>
</asp:ScriptManager>

Figure 2-2: ScriptManager schema


<asp:ScriptManager ID="ScriptManager1" runat="server"
EnablePartialRendering="true|false"
EnablePageMethods="true|false"
AsyncPostBackTimeout="seconds"
AsyncPostBackErrorMessage="message"
AllowCustomErrorsRedirect="true|false"
OnAsyncPostBackError="handler"
EnableScriptGlobalization="true|false"
EnableScriptLocalization="true|false"
ScriptMode="Auto|Inherit|Debug|Release"
ScriptPath="path">
<Scripts>
<!-- Declare script references here -->
</Scripts>
<Services>
<!-- Declare Web service references here -->
</Services>
</asp:ScriptManager>

Additional configuration options can be specified through properties of the


ScriptManager control. For example, setting EnablePartialRendering to true allows the
page to host UpdatePanel controls, while ScriptMode=“Debug” runs the debug version
of the Microsoft AJAX Library rather than the release version.

The ScriptManager control’s Error properties provide control over error handling. By
default, if an exception is thrown during an asynchronous ASP.NET AJAX callback, the
custom error page registered in the <customErrors> section of Web.config is displayed.
If no custom error page is designated, then ASP.NET AJAX displays the exception’s
Message property in an alert window on the client. You can set the
AllowCustomErrorRedirect property to false to prevent custom error pages from being
shown, and use the AsyncPostBackErrorMessage property to override the default error
message with a custom one. Additionally, you can use the OnAsyncPostBackError event
to execute a handler on the server if an exception occurs during an asynchronous
callback. From the handler, you can specify the error message returned to the client.

The ScriptManager control is complemented by the ScriptManagerProxy control. If you


declare a ScriptManager control in a master page and want to declare additional script
or service references in a content page, you can declare a ScriptManagerProxy control
in the content page and add your script and service references there, as illustrated in
Figure 2-3.

Figure 2-3: Using the ScriptManagerProxy control


2.1.2 UpdatePanel
Sometimes called the “crown jewel of ASP.NET AJAX,” the UpdatePanel control is
more aptly described as “partial-page rendering in a box.” It so thoroughly abstracts
the mechanics of partial-page rendering that using it completely shields the developer
from having to understand XML-HTTP and JavaScript.

Figure 2-4 illustrates how UpdatePanel controls perform partial-page rendering, and
why partial-page rendering eliminates the excessive flashing that characterizes many
ASP.NET Web pages. In a traditional update, the page posts back to the server. The
browser erases the page and redraws it using the content returned in the response. A
page with an UpdatePanel control works differently. The UpdatePanel automatically
converts postbacks from controls inside it into asynchronous XML-HTTP callbacks. The
browser doesn’t erase the page, and when the callback completes, the UpdatePanel
control updates its content using JavaScript. Thus, less rendering is performed on the
server (only controls inside the UpdatePanel undergo a rendering cycle), less data
comes back in the response, and the user experience is improved because the page
doesn’t flash.

Figure 2-4: Partial-page rendering with UpdatePanel controls


To use an UpdatePanel control, you simply declare it on the page where you want
partial-page rendering to take place and then put the content in a <ContentTemplate>
element, as demonstrated in Figure 2-5.

Figure 2-5: Using an UpdatePanel control


<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<!-- Declare content here -->
</ContentTemplate>
</asp:UpdatePanel>

If the <ContentTemplate> contains Buttons or LinkButtons or other controls that


generate postbacks, the UpdatePanel control converts the postbacks into asynchronous
callbacks. The page looks no different than before, but when a control in the
UpdatePanel posts (calls) back to the server, the UpdatePanel control replaces the old
markup in the <ContentTemplate> with the new markup returned in the response,
producing a clean, flicker-free refresh.

The UpdatePanel control also supports explicitly defined triggers. Triggers come in
two varieties. The AsyncPostBackTrigger allows controls outside an UpdatePanel to
trigger updates of the UpdatePanel’s content. Under the hood, AsyncPostBackTrigger
converts postbacks generated by the specified controls into asynchronous callbacks.
The other trigger type, PostBackTrigger, allows controls inside an UpdatePanel to post
back rather than call back. In Figure 2-6, the UpdatePanel control converts postbacks
from all the controls declared inside it and postbacks generated by a Button control
outside the UpdatePanel into asynchronous callbacks that refresh the UpdatePanel:
Figure 2-6: UpdatePanel triggers
<asp:Button ID="Button1" Text="Click Me"
OnClick="Button1_Clicked" runat="" />
...
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1"
EventName="Click" />
</Triggers>
<ContentTemplate>
<!-- Declare content here -->
</ContentTemplate>
</asp:UpdatePanel>

On the server, the Button control’s Click handler—Button1_Clicked—is called inside


the callback just as if a conventional postback had occurred. This is one of the
UpdatePanel control’s greatest assets: the fact that you can write code using the same
server-centric model you’re accustomed to in ASP.NET. The code works as if a
postback had occurred, and the UpdatePanel control eliminates flashing and flickering
on the client.

UpdatePanel controls are frequently combined with Timer controls to periodically


refresh content on a page. This is one way to synchronize data displayed in a browser
with data that is continually changing on a server.

A page can contain multiple UpdatePanel controls. By default, when an update is


triggered in one UpdatePanel control, other UpdatePanel controls on the page
rerender, too. In some cases, that’s what you want; in most cases, it’s not. (More
UpdatePanel controls updating in response to a callback means more rendering code
executes on the server and more data comes back in the response.) To selectively
trigger updates, you can set each UpdatePanel control’s UpdateMode property to
“Condtional” (the default is “Always”), When an event handler is called inside a
callback from one UpdatePanel control, you then call the Update method of other
UpdatePanels that need updating. When UpdateMode=“Conditional,” an UpdatePanel
control only rerenders its contents if one of the controls inside it triggers a callback or
its Update method is called.

In order for an UpdatePanel control to work, the page that hosts it must also contain a
ScriptManager control. In addition, the ScriptManager control must be configured to
enable partial-page rendering, as shown here:

<asp:ScriptManager ID="ScriptManager1" runat="server"


EnablePartialRendering="true" />

The EnablePartialRendering=“true” attribute ensures that the JavaScript file


containing the client-side support that UpdatePanel requires is downloaded to the
browser. Because the EnablePartialRendering property defaults to true, simply
declaring a ScriptManager control on the page (without explicitly setting
EnablePartialRendering to true) is sufficient to enable partial-page rendering.

Most controls can be hosted inside an UpdatePanel, but some cannot. In particular,
controls that emit JavaScript of their own cause myriad problems with UpdatePanel
controls unless they use RegisterClientScriptBlock, RegisterStartupScript, and other
ScriptManager registration methods to register the script they return. For more
information on script registration and how to build custom controls that are
compatible with the UpdatePanel control, read the post entitled “HOWTO: Write
controls compatible with UpdatePanel without linking to the ASP.NET AJAX DLL” by
Eilon Lipton, lead developer of the UpdatePanel control, at
http://forums.asp.net/thread/1445844.aspx.

The UpdatePanel control does have one drawback: its callbacks aren’t as efficient on
the wire as hand-coded AJAX callbacks. The data transmitted to the server includes
view state and other form input and is in fact almost identical to what’s transmitted in
a traditional postback. The response includes all the freshly rendered content. The
size of that content is roughly proportional to the size of the UpdatePanel control’s
<ContentTemplate>. In other words, if the UpdatePanel control encompasses half the
page, then the response size is roughly half that generated by a traditional postback.
UpdatePanel callbacks aren’t as efficient as hand-coded AJAX callbacks once they
reach the server, either, because the page undergoes a nearly complete life cycle.
Techniques exist for optimizing UpdatePanel usage and even replacing UpdatePanel
controls with Web services and JavaScript, but those techniques are beyond the scope
of this document. Suffice it to say that UpdatePanel controls emphasize ease-of-use
over efficiency—proof once more that there’s no such thing as a free lunch.

2.1.3 UpdateProgress
The UpdateProgress control is a companion to the UpdatePanel control. It enables
pages that host UpdatePanel controls to display special content elements when an
update is in progress—for example, an animated GIF depicting a progress bar or a clock
with spinning hands. It can also be used to display UIs for canceling updates that
haven’t completed.

The markup in Figure 2-7 declares an UpdateProgress control that displays an


animated GIF each time an UpdatePanel control updates and hides the GIF when the
update completes. DisplayAfter=“500” prevents the image from being shown if the
update requires less than half a second (500 milliseconds) to complete.

Figure 2-7: Using the UpdateProgress control


<asp:UpdateProgress ID="UpdateProgress1" runat="server"
DisplayAfter="500">
<ProgressTemplate>
<asp:Image ID="ProgressBarImage" runat="server"
ImageUrl="~/Images/ProgressBar.gif" />
</ProgressTemplate>
</asp:UpdateProgress>
You can create more sophisticated progress UIs by declaring them in the control’s
<ProgressTemplate>. The example in Figure 2-8 displays a Cancel button if the update
takes more than 1 second to complete, and it uses a bit of JavaScript to cancel the
update if the button is clicked:

Figure 2-8: Canceling a pending update


<asp:UpdateProgress ID="UpdateProgress1" runat="server"
DisplayAfter="1000">
<ProgressTemplate>
<asp:Button ID="CancelButton" runat="server" Text="Cancel"
OnClientClick="cancelUpdate(); return false;" />
</ProgressTemplate>
</asp:UpdateProgress>

<script type="text/javascript">
function cancelUpdate()
{
var obj = Sys.WebForms.PageRequestManager.getInstance();
if (obj.get_isInAsyncPostBack())
obj.abortPostBack();
}
</script>

By default, if a page contains just one UpdateProgress control, the control displays its
content when any UpdatePanel control on the page updates. However, you can
declare multiple UpdateProgress controls on a page and associate each with a specific
UpdatePanel using the UpdateProgress control’s AssociatedUpdatePanelID property.
This is useful when a page contains multiple UpdatePanel controls and you want to
display a different progress UI for each one.

2.2 ASP.NET AJAX Control Toolkit Server Controls


The ASP.NET AJAX Control Toolkit expands the capabilities of the ASP.NET 2.0 AJAX
Extensions by adding more than 30 new server controls. Figure 2-9 lists the controls
included in the toolkit as of January 2007.

Figure 2-9: ASP.NET AJAX Control Toolkit server controls

Control Description
Accordion Displays “accordion” UI consisting of multiple
panes, only one of which is visible at a time.
AlwaysVisibleControlExtender Pins controls in a specified position as the page
is scrolled or resized.
AnimationExtender Adds animation effects to Web pages.
AutoCompleteExtender Adds context-sensitive drop-down completion
lists to TextBox controls.
Calendar Adds popup calendars to date-entry TextBox
controls.
CascadingDropDown Connects DropDownList controls so that a
change to one updates content in the others.
CollapsiblePanelExtender Implements content panels that can be
interactively expanded and collapsed.
ConfirmButtonExtender Enhances button controls with popup
confirmation boxes.
DragPanelExtender Enables Panel controls to be interactively
dragged and repositioned.
DropDownExtender Adds SharePoint-style drop-down menus to
other controls.
DropShaow Adds drop shadows to Panel controls.
DynamicPopulateExtender Populates controls by calling Web methods or
page methods asynchronously.
FilteredTextBoxExtender Filters input to TextBox controls.
HoverMenuExtender Adds popup “hover” menus to other controls.
MaskedEditExtender Adds visual formatting cues to TextBox
controls.
ModalPopupExtender Displays content modally.
MutuallyExclusiveCheckBoxExtender Groups CheckBox controls and ensures that
only one member of the group is checked.
NoBot Uses challenge-response mechanism to filter
out “bot” input without user intervention.
NumericUpDownExtender Adds up-down buttons to TextBox controls.
PagingBulletedListExtender Adds sorting and paging to BulletedList
controls.
PasswordStrength Enhances password-entry TextBox controls with
visible indication of password strength.
PopupControlExtender Attaches popup content to other controls.
Rating Displays interactive rating UI.
ReorderList Implements lists whose items can be reordered
by the user.
ResizableControlExtender Allows content to be resized interactively.
RoundedCornersExtender Adds rounded corners to existing elements.
SliderExtender Adds sliders to TextBox controls.
TabContainer and TabPanel Implements interactive tabbed UI.
TextBoxWatermarkExtender Adds watermark text to TextBox controls.
ToggleButtonExtender Enhances CheckBox controls with images that
toggle between checked and unchecked mode.
UpdatePanelAnimationExtender Plays animations when UpdatePanel controls
update.
ValidatorCalloutExtender Adds popup UIs to ASP.NET validator controls.

One of the most compelling controls in the ASP.NET AJAX Control Toolkit is the
AutoCompleteExtender control, which adds context-sensitive drop-down completion
lists to TextBox controls (see Figure 2-10). As the user types, the list is updated, and
at any time the user can stop typing and simply choose an item from the list. Items in
the list come from a Web service, and it is the developer’s responsibility to provide
that Web service. AutoCompleteExtender does the rest, automatically calling the Web
service each time the text in the TextBox changes and passing as input what the user
has typed thus far.

Figure 2-10: TextBox control with a drop-down completion list

Figure 2-11 shows how AutoCompleteExtender controls are declared in Web pages.
The TargetControlID property identifies the TextBox that the AutoCompleteExtender
control extends, while ServicePath and ServiceMethod identify the Web service and
Web method that are called on each keystroke to generate a context-sensitive
completion list. (The Web service is a conventional ASMX Web service tagged with the
ScriptService attribute described in Section 2.4.) MinimumPrefixLength=”2” instructs
the AutoCompleteExtender to make the first call to the Web service after two
characters have been typed, and CompletionSetCount=”20” tells it to display up to 20
items in the completion list. If desired, you can also use the CompletionListElementID
property to identify an ASP.NET Panel control that acts as a proxy for the completion
list. Explicitly declaring the completion list in this way is useful for styling it using
control properties or CSS.

Figure 2-11: Using the AutoCompleteExtender control


<asp:TextBox ID="ZipCodeTextBox" runat="server" />
...
<ajaxToolkit:AutoCompleteExtender runat="server"
ID="ZipCodeAutoCompleteExtender"
TargetControlID="ZipCodeTextBox"
ServicePath="ZipCodeService.asmx"
ServiceMethod="GetMatchingZipCodes"
MinimumPrefixLength="2"
CompletionSetCount="20"
/>

The Web method called to generate the completion list can have any name you want,
but it must have the following signature:
public string[] GetMatchingZipCodes(string prefixText,
int count);

When the method is called, prefixText specifies the text currently displayed in the
TextBox, and count specifies the maximum number of strings to return in the string
array. The strings returned by the method are used to populate the completion list.

2.3 ASP.NET AJAX Futures CTP Server Controls


The ASP.NET AJAX January Futures CTP adds two server controls to the ASP.NET 2.0
AJAX Extensions: the DragOverlayerExtender control and the ProfileService control.
The former adds drag-drop support to existing controls; the latter can be used to
persist the positions of controls paired with DragOverlayExtender controls.

The DragOverlayExtender control extends existing ASP.NET controls such as Image


controls and Panel controls by making them “floatable.” Users can reposition floatable
elements with their mouse. The DragOverlayExtender control relies on the rich drag-
and-drop support present in the Microsoft AJAX Library. It provides no explicit support
for drag-sourcing or drop-targeting (for example, it does not raise an event when a
drop occurs or provide control over when and where drops occur), even though the
drag-and-drop classes in the Microsoft AJAX Library offer support for all this and more.

The markup in Figure 2-12 declares an Image control and converts it into a floatable
image with a DragOverlayExtender control. The TargetControlID property identifies
the Image. DragOverlayExtender can be applied to Panels, Images, and a variety of
other control types, but it cannot be used with controls that generate HTML <input>,
<button>, <select>, <textarea>, or <label> elements. You can’t, for example, apply a
DragOverlayExtender control to a TextBox control.

Figure 2-12: Using the DragOverlayExtender control to create a floatable image


<asp:Image ID="Logo" runat="server"
ImageUrl="~/Images/Company_Logo.jpg" />
...
<asp:DragOverlayExtender runat="server"
ID="DragOverlayExtender1"
TargetControlID="Logo"
Enabled="true"
/>

By default, the positions of elements floated with DragOverlayExtender are not


persistent; elements snap back to their original positions when the page is refreshed
or revisited. You can make them persistent by combining DragOverlayExtender with a
ProfileService control. The ProfileService control uses the ProfileService Web service
in the ASP.NET 2.0 AJAX Extensions to communicate with the ASP.NET 2.0 profile
service on the server and to store positions on a per-element, per-user basis. The
ProfileService Web service is discussed in Section 2.7.2.
2.4 Web Services
Virtually all AJAX frameworks provide a means to call methods on the server using
asynchronous XML-HTTP requests. ASP.NET AJAX is no exception. The primary
mechanism for exposing callback methods to JavaScript clients in ASP.NET AJAX is the
ASMX Web method. (Windows Communication Foundation Web services will be
supported in a future release.)

To make an ASMX Web service accessible from ASP.NET AJAX clients, you first
attribute the Web service class with a System.Web.Script.Services.ScriptService
attribute. (This attribute can be applied in lieu of or in addition to the traditional
WebService attribute.) Figure 2-12 shows the C# code-behind class for a simple Web
service whose lone Web method is callable from JavaScript.

Figure 2-12: Code-behind class for a Web service that’s callable from JavaScript
[System.Web.Script.Services.ScriptService]
public class ZipCodeService : System.Web.Services.WebService
{
[WebMethod]
public string[] GetCityAndState(string zip)
{
...
}
}

The next step is to add a service reference. The service reference identifies the Web
service by URL and downloads a JavaScript proxy through which the Web service can
be called. Service references can be created declaratively using the <Services>
element of a ScriptManager or ScriptManagerProxy control, as shown in Figure 2-13.

Figure 2-13: Declaring a service reference


<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/ZipCodeService.asmx" />
</Services>
</asp:ScriptManager>

The JavaScript proxy generated by the service reference has the same name as the
Web service class. Figure 2-14 demonstrates how an ASP.NET AJAX client can call the
GetCityAndState method shown in Figure 2-12 to convert a ZIP code into a city and
state. The call is asynchronous, so the parameter list on the client always contains at
least one more parameter than the parameter list on the server. The extra parameter
is the name of the JavaScript function that’s called when the asynchronous callback
completes.
Figure 2-14: Calling the GetCityAndState method from JavaScript
ZipCodeService.GetCityAndState("98052", onComplete);
...
function onComplete (result)
{
window.alert(result);
}

In practice, you’ll probably want to know if the callback fails so you can respond
gracefully. Figure 2-15 demonstrates how to call GetCityAndState and specify a
JavaScript function (onFailed) that’s called if the call fails—for example, if an
exception is thrown on the server or the call times out.

Figure 2-15: Handling errors in Web service calls


ZipCodeService.GetCityAndState("98052", onCompleted, onFailed);
...
function onCompleted (result, context, methodName)
{
window.alert(result);
}

function onFailed (err, context, methodName)


{
window.alert(err.get_message());
}

In traditional ASP.NET applications, Web service calls use XML and SOAP. Calls to Web
services from ASP.NET AJAX clients are very different. By default, data is encoded in
JSON (more on this in Section 2.6), and the packet format is a custom one that is much
lighter-weight than SOAP. Moreover, none of the view state and other form input that
travels to the server in a normal ASP.NET postback is transmitted. The net result is
maximum efficiency on the wire and little wasted motion on either the client or
server.

Figure 2-16 shows the request and response packets generated when the
GetCityAndState method is called through a JavaScript proxy generated by ASP.NET
AJAX. The actual payload—the request and response bodies—contain JSON-encoded
input and output and nothing more. Clearly, calling ASMX endpoints from ASP.NET
AJAX clients is both lightweight and efficient.

Figure 2-16: Request and response generated by a call to GetCityAndState


2.4.1 Web Service Extensions
Much of the magic that underlies asynchronous XML-HTTP requests to ASMX endpoints
lie in the Web service extensions included in the ASP.NET 2.0 AJAX Extensions. These
extensions allow the requests to be handled on the server, provide the JSON support
needed to serialize and deserialize parameters and return values, and generate the
JavaScript proxies.

When you declare a service reference like the one in Figure 2-13, the ScriptManager
control emits the following markup:

<script src="ZipCodeService.asmx/js" type="text/javascript">


</script>

The browser submits an HTTP request for ZipCodeService.asmx/js, and the server
responds by returning a JavaScript proxy. (You can see the proxy by manually
submitting the same request yourself, or by including an InlineScript=”true” attribute
in the <asp:ServiceReference> tag and then examining the resulting source code in
your browser.)

How does the server know how to handle an ASMX request with a “/js” at the end?
Because of the following statements in the <httpHandlers> section of the Web.config
file of an ASP.NET AJAX Web site, which map all requests for ASMX resources to an
ASP.NET 2.0 AJAX Extensions class named ScriptHandlerFactory:
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false"
type="System.Web.Script.Services.ScriptHandlerFactory, ..."
/>

ScriptHandlerFactory delegates “normal” ASMX requests to the default ASMX handler


(System.Web.Services.Protocols.WebServiceHandlerFactory). But when it sees special
extensions such as “/js” in the URL, it handles the requests itself—or rather, handles
them by delegating to other classes in System.Web.Extensions.dll, as shown in Figure
2-17. One of the key classes represented by the block labeled “Helper Classes” is
WebServiceClientProxyGenerator, which generates JavaScript proxies.

Figure 2-17: ASMX request processing

Notice the URL targeted by the HTTP request in Figure 2-16:

/AtlasRC/ZipCodeService.asmx/GetCityAndState

When a client places a call to a Web method through a JavaScript proxy, the proxy
appends the method name to the URL. The request is ultimately processed by the
RestHandler class, which deserializes the input parameters, invokes the Web method,
and returns the serialized output to the caller.

Although ASP.NET AJAX currently supports only ASMX Web services, support could be
added for other Web service platforms by extending those platforms to support the
same special URL semantics as ScriptHandlerFactory and friends.
2.4.2 The ScriptMethod Attribute
The GetCityAndState method in Figure 2-12 is decorated with the WebMethod
attribute used in virtually all ASMX Web services. Web methods called from JavaScript
can alternatively be marked with the ASP.NET 2.0 AJAX Extensions’
System.Web.Script.Services.ScriptMethod attribute, which provides added control
over the format of the data that passes over the wire. Key properties of the attribute
include:

• ResponseFormat, which specifies whether output values should be serialized


into JSON (ResponseFormat.Json) or XML (ResponseFormat.Xml). The default is
ResponseFormat.Json.

• UseHttpGet, which, if true, generates JavaScript proxies that invoke script


methods using HTTP GETs rather than HTTP POSTs. The default is false.

• XmlSerializeString, which, if true and if the response format is


ResponseFormat.Xml, serializes all values in the response, including strings,
into XML. The default is false.

The ResponseFormat property is particularly useful for serializing data types that
aren’t compatible with JSON into XML, and with methods that return XML data. The
following Web method uses a ScriptMethod attribute to prevent an XmlDocument from
being serialized into JSON:

[ScriptMethod (ResponseFormat=ResponseFormat.Xml)]
public XmlDocument GetData()
{
...
}

Of course, the XML must be parsed on the client to extract data from it.

2.5 Page Methods


In addition to allowing conventional Web methods to serve as targets for XML-HTTP
requests, ASP.NET AJAX also supports a special type of Web method known as the page
method. Page methods are Web methods implemented in Web pages—that is, in ASPX
files or code-behind files rather than in ASMX files. Page methods enable developers to
provide endpoints for XML-HTTP callbacks without building dedicated Web services.

Page methods must be public static methods and must be decorated with the
WebMethod or ScriptMethod attribute. (The latter performs the same function for
page methods as it does for Web methods.) Figure 2-18 shows the C# code-behind class
for a page that implements the GetCityAndState method from Figure 2-12 as a page
method rather than as an ASMX Web method.

Figure 2-18: Code-behind class containing a page method


public partial class MyPage : System.Web.UI.Page
{
[WebMethod]
public static string[] GetCityAndState(string zip)
{
...
}
}

On the client, page methods are called from JavaScript through the special
PageMethods proxy, as shown in Figure 2-19. Page methods don’t require service
references as Web services do. That is, you don’t need to declare a service reference
in a ScriptManager (or ScriptManagerProxy) control to facilitate calls to page methods.
You do, however, have to enable page methods by setting a ScriptManager control’s
EnablePageMethods property to true:

<asp:ScriptManager ID="ScriptManager1" runat="server"


EnablePageMethods="true" />

Setting EnablePageMethods to true downloads the PageMethods proxy to the client. If


EnablePageMethods is false, PageMethods is undefined on the client even if the page
contains page methods.

Figure 2-19: Calling a page method from JavaScript


PageMethods.GetCityAndState("98052", onCompleted, onFailed);
...
function onCompleted (result, context, methodName)
{
window.alert(result);
}

function onFailed (err, context, methodName)


{
window.alert(err.get_message());
}

Under the hood, page methods offer the same efficiency as Web methods. View state
and other input is not transmitted to the server when page methods are called, and
because page methods are static, the ASP.NET 2.0 AJAX Extensions can call them
without instantiating a page object. A call to a page method does not invoke the page
life cycle that is triggered by conventional ASP.NET requests.

2.6 JSON
ASP.NET AJAX clients that call Web methods and page methods aren’t limited to
passing strings and other primitive data types; they can pass complex data types, too.
By default, ASP.NET AJAX serializes data passed to and from Web methods and page
methods using the industry-standard JavaScript Object Notation (JSON) format. JSON
is a lightweight data interchange format whose syntax is based on JavaScript itself. It
is less verbose than XML (leading to greater efficiency on the wire) and easier to parse
and deserialize, thanks in part to the JavaScript eval function. In an ASP.NET AJAX
client, JSON support is provided by the Sys.Serialization.JavaScriptSerializer class. On
the server, it’s provided by the System.Web.Script.Serialization.JavaScriptSerializer
class.

Suppose a Web method or page method returns a Point object—an instance of the .NET
Framework’s System.Drawing.Point type. Under the hood, the ASP.NET 2.0 AJAX
Extensions call JavaScriptSerializer.Serialize to serialize the Point object. If the
object’s X and Y properties are initialized to 100 and 200, respectively, here’s the
JSON representation of the object passed over the wire to the caller:

{"IsEmpty":false,"X":100,"Y":200}

Had the Point object been serialized with the .NET Framework’s XML serializer
instead, it would have been serialized this way:

<?xml version="1.0"?>
<Point xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<X>100</X>
<Y>200</Y>
</Point>

On the client, the JSON-serialized Point object can be handled this way:

WebServiceName.GetPoint(onComplete);
...
function onComplete(result)
{
// Displays "100, 200"
window.alert(result.X + ', ' + result.Y);
}

The Microsoft AJAX Library’s JavaScriptSerializer.deserialize method turns the JSON


string representation of the object ({"IsEmpty":false,"X":100,"Y":200}) into a JavaScript
object. This is transparent to the developer, who simply passes objects back and forth
in method calls and relies on ASP.NET AJAX to serialize and deserialize them as
needed.

Not all types are JSON-compatible. JSON does not, for example, include provisions for
handling circular references. When you need to return complex data types that aren’t
JSON-compatible, you can use the ScriptMethod attribute with the response format
set to ResponseFormat.Xml to serialize the types into XML as described in Section
2.4.2. Alternatively, you can build and register custom JSON converters that allow
types that aren’t normally JSON-compatible to be serialized and deserialized. The
ASP.NET AJAX January Futures CTP contains three such converters: one for DataSets,
one for DataTables, and one for DataRows.

ASP.NET AJAX’s JSON serializers provide special handling for one common .NET data
type that isn’t handled natively by JSON: System.DateTime. The serialization format
used is specific to .NET and would require special handling to be used on other
platforms.

2.7 Built-In Web Services


ASP.NET AJAX includes two built-in Web services (and corresponding client proxies)
that enable JavaScript clients to call the ASP.NET 2.0 membership and profile services
on the server. Together, these Web services form the application services bridge
depicted in Figure 1-2.

2.7.1 AuthenticationService
Sys.Services.AuthenticationService, which is an instance of the
Sys.Services._AuthenticationService class defined in the Microsoft AJAX Library, is the
client-side proxy for the ASP.NET 2.0 membership service.
Sys.Services.AuthenticationService methods enable JavaScript clients to log users in
and out (login and logout) and determine whether they’re currently logged in
(get_isLoggedIn) by invoking the membership service on the server. The JavaScript
code in Figure 2-20 attempts to log in a user by passing a user name and password.
The result parameter passed to onLoginCompleted indicates whether the login
succeeded (that is, whether the supplied credentials were valid and the user is
currently permitted to log in). If the call itself fails (rather than the login),
onLoginFailed is called instead.

Figure 2-20: Using Sys.Services.AuthenticationService to log in a user


Sys.Services.AuthenticationService.login(username, password,
false, null, null, onLoginCompleted, onLoginFailed);
...
function onLoginCompleted(result, context, methodName)
{
window.alert(result ? 'Login succeeded' : 'Login failed');
}

function onLoginFailed(err, context, methodName)


{
window.alert(err.get_message());
}

In order for this to work, the authentication mode must be set to “Forms” on the
server. In addition, the ASP.NET AJAX Web service that front-ends the membership
service on the server must be enabled. (It is disabled by default). The following
configuration section enables the Web service:

<microsoft.web>
<scripting>
<webServices>
<authenticationService enabled="true" />
</webServices>
</scripting>
</microsoft.web>

The <authenticationService> configuration element also supports a Boolean requireSSL


attribute that indicates whether calls to the Web service must travel over encrypted
connections. The defaut is false. In practice, requireSSL should always be set to true
to prevent user names and passwords from being transmitted in plain text.

2.7.2 ProfileService
A separate JavaScript proxy named Sys.Services.ProfileService (an instance of the
Sys.Services._ProfileService class defined in the Microsoft AJAX Library) provides a
client-side interface to the ASP.NET 2.0 profile service. It enables JavaScript clients to
use the profile service to store per-user data persistently. One use for this feature is
to store personalization data in back-end databases on the server (as opposed to
storing it in cookies, for example).

Sys.Services.ProfileService exposes two methods for loading and saving profile


property values: load and save. It also exposes a property named properties through
which property values are accessed. Figure 2-21 shows how to load a profile property
named ScreenName for the current user; Figure 2-22 shows how to save it. The first
parameter passed to load and save is an array of profile property names. To load or
save several property values, simply pass an array containing all the property names.

Figure 2-21: Reading profile properties from the client


Sys.Services.ProfileService.load(['ScreenName'], onLoadCompleted,
onLoadFailed);
...
function onLoadCompleted(result, context, methodName)
{
window.alert
(Sys.Services.ProfileService.properties.ScreenName);
}

function onLoadFailed(err, context, methodName)


{
window.alert(err.get_message());
}

Figure 2-22: Saving profile properties from the client


Sys.Services.ProfileService.properties.ScreenName = 'Bob';
Sys.Services.ProfileService.save(['ScreenName'], onSaveCompleted,
onSaveFailed);
...
function onSaveCompleted(result, context, methodName)
{
window.alert('Save succeeded');
}
function onSaveFailed(err, context, methodName)
{
window.alert(err.get_message());
}

Profile properties must be defined on the server before they can be accessed from the
client. The following configuration section defines a profile containing a single string-
type property named ScreenName:

<system.web>
<profile>
<properties>
<add name="ScreenName" />
</properties>
</profile>
</system.web>

Like the authentication Web service, the profile Web service must be enabled before
it can be used. The following example shows how to enable it and expose the
ScreenName property to the client:

<microsoft.web>
<scripting>
<webServices>
<profileService enabled="true"
readAccessProperties="ScreenName"
writeAccessProperties="ScreenName"
/>
</webServices>
</scripting>
</microsoft.web>

Only properties identified using the readAccessProperty and writeAccessProperty


attributes can be read and written with Sys.Services.ProfileService, no matter how
many profile properties are defined. To expose multiple profile properties to the
client, pass comma-delimited lists of property names to readAccessProperties and
writeAccessProperties.
3.0 The Microsoft AJAX Library
The Microsoft AJAX Library is the name given to the JavaScript library that makes up
the client half of ASP.NET AJAX. Written in 100% JavaScript, it extends JavaScript by
adding new functions, a JavaScript type system, support for classes and namespaces
and other features of object-oriented programming (OOP), and an extensive library of
classes that make JavaScript a richer and more productive language in which to work.
Moreover, it works in a variety of browser types, including Internet Explorer, Firefox,
and Apple Safari.

The Microsoft AJAX Library is independent of server platforms. It can be used with or
without the ASP.NET 2.0 AJAX Extensions, and developers can easily build pages in
PHP, ColdFusion, and other languages that emit JavaScript code that leverages the
Microsoft AJAX Library—just as pages built with the ASP.NET 2.0 AJAX Extensions do.

The Microsoft AJAX Library is physically packaged in the JavaScript files listed in
Figure 3-1. The files come in both debug and release versions. The release versions are
stripped down to the bare essentials (even white space is removed) to minimize
download size. ASP.NET developers use ScriptManager and ScriptManagerProxy
controls to download these files to the client. However, developers who want to use
the Microsoft AJAX Library with other platforms can use <script> elements to download
the files.

Figure 3-1: Core Microsoft AJAX Library JavaScript files


File Description
MicrosoftAjax.js Type system, base type extensions, networking classes,
and other core infrastructure
MicrosoftAjaxTimer.js _Timer class implementing client-side programmable
timer
MicrosoftAjaxWebForms.js PageRequestManager and other classes that support
partial-page rendering

The Microsoft AJAX Library is factored into individual files for download granularity. By
default, MicrosoftAjax.js is the only file downloaded. The uncompressed size of the
release version is 79K, and after the file is GZIPped, the size drops to approximately
15K on the wire. Pages that use UpdatePanel controls also download
MicrosoftAjaxWebForms.js, which adds another 5K or so to the compressed download.
Browsers cache JavaScript files, so between the compactness of the compressed files
and the fact that they aren’t downloaded very often, users shouldn’t notice the
downloads and in fact probably won’t be aware that the files were downloaded.

The ASP.NET AJAX January Futures CTP extends the Microsoft AJAX Library with the
JavaScript files listed in Figure 3-2. These files aren’t required if you only use the core
features of ASP.NET AJAX, but they add to the platform a variety of useful features
including support for animations and drag-and-drop operations.
Figure 3-2: January Futures CTP JavaScript files
File Description
PreviewScript.js Extensive library of classes (including control classes)
PreviewGlitz.js Animation classes and other classes for building
“glitzy” UIs
PreviewDragDrop.js _DragDropManager and other classes that support drag-
and-drop operations
PreviewWebParts.js AJAX support for ASP.NET Web parts

The sections that follow document the content and structure of the Microsoft AJAX
Library (including some of the features added by the January Futures CTP) and provide
helpful guidance to developers who are interested in understanding and extending it.

3.1 JavaScript Base Type Extensions


To make JavaScript easier to work with, the Microsoft AJAX Library adds new functions
to the JavaScript Array, Boolean, Date, Error, Number, Object, and String data types.
These extensions are implemented in MicrosoftAjax.js and are documented at
http://ajax.asp.net/docs/ClientReference/Global/JavascriptTypeExtensions/default.a
spx. Figure 3-3 provides a brief summary of the functions that are added.

Figure 3-3: JavaScript base type extensions


Type Functions Added
Array add, addRange, clear, clone, contains, dequeue, enqueue, forEach,
indexOf, insert, parse, remove, removeAt
Boolean parse
Date format, localeFormat, parseLocale, parseInvariant
Error argument, argumentNull, argumentOutOfRange, argumentType,
argumentUndefined, create, format, invalidOperation,
notImplemented, parameterCount, popStackFrame
Number format, localeFormat, parseLocale, parseInvariant
Object getType, getTypeName
String endsWith, format, localeFormat, startsWith, trim, trimEnd, trimStart

Here’s a quick example of the base type extensions in use:

var s = String.format ('{0}, {1}, and {2}', 1, 2, 3);


window.alert (s); // Displays "1, 2, and 3"

This example uses the String.format function, which is similar to the .NET
Framework’s String.Format method, to build a string without using concatenation
operators.

3.2 Global Functions and Variables


In addition to enhancing JavaScript base types, the Microsoft AJAX Library defines
several global functions and variables designed to make programming and debugging
easier (and for use elsewhere in the Microsoft AJAX Library). Figure 3-4 lists the global
functions; documentation regarding them can be found at
http://ajax.asp.net/docs/ClientReference/Global/default.aspx. Look through the
Microsoft AJAX Library source code and you’ll see these functions used extensively.

Figure 3-4: Global functions defined in the Microsoft AJAX Library


Function Description
$addHandler Registers a handler for a DOM event
$addHandlers Registers handlers for DOM events
$clearHandlers Unregisters handlers for DOM events
$removeHandler Unregisters a handler for a DOM event
$create Creates an initializes a component
$find Returns a reference to the specified component
$get Returns a reference to the specified DOM element (equivalent
to document.getElementById)

The Microsoft AJAX Library defines several global variables that provide easy access
from anywhere to parts of its own infrastructure. Among them are Sys.Application,
which represents the application and refers to an instance of Sys._Application;
Sys.Services.AuthenticationService, which provides access to the ASP.NET 2.0
membership service on the server (see Section 2.7.1); and Sys.Services.ProfileService,
which provides access to the ASP.NET 2.0 profile service on the server (see Section
2.7.2).

The Microsoft AJAX Library also creates an instance of its own Sys._Debug class and
assigns a reference to it to the global variable Sys.Debug. Sys._Debug contains useful
methods to assist in debugging, including assert, fail, trace, and traceDump,
facilitating JavaScript code like the following:

// Assert
var happy = false;
Sys.Debug.assert(happy == true, 'happy is NOT true', false);

// Break into the debugger


Sys.Debug.fail('Somebody is NOT happy');

3.3 JavaScript Type System (Adding OOP to JavaScript)


JavaScript is an object-based language, but not an object-oriented one. It has no
intrinsic support for classes, namespaces, inheritance, or other features found in
object-oriented languages such as C++ and C#.

The Microsoft AJAX Library changes that by adding OOP to JavaScript. At least it
creates the illusion of OOP; in truth, all it’s doing is making creative use of JavaScript
to make it seem as if you can define classes, namespaces, interfaces, and so on. But
the illusion is an effective one, and it is the foundation for the types featured in the
Script Core Library and the Base Class Library discussed in the next two sections.
To make JavaScript seem more like an object-oriented programming language, the
Microsoft AJAX Library exploits the fact that JavaScript allows functions to be treated
as data types and instantiated with the new operator. It also uses the prototype
property introduced in JavaScript 1.1 to make functions feel more like classes and to
enact the JavaScript equivalent of inheritance.

As an example, the code in Figure 3-5 implements a JavaScript “class” named Point.
The Point function acts as a constructor, and the statements inside the function
declare and initialize what are essentially instance fields named _x and _y.
Point.prototype is then used to define get_x and get_y methods that are included in
all instances of Point. This class implementation makes the following JavaScript code
perfectly legal:

p = new Point(100, 200);


alert(p.get_x() + ", " + p.get_y()); // Displays "100, 200"

Purists might argue that this isn’t really OOP, but it certainly feels like OOP. And it’s
very similar to the pattern that the Microsoft AJAX Library uses to implement classes.

Figure 3-5: JavaScript Point class


Point = function(x, y)
{
this._x = x;
this._y = y;
}

Point.prototype =
{
get_x: function() { return this._x; },
get_y: function() { return this._y; }
}

Of course, most OOP programming languages support more than just classes; they also
support namespaces, interfaces, base classes and derived classes, and the like. Some
even support type reflection so that information about types can be discovered at run-
time.

Enter the second ingredient in the Microsoft AJAX Library’s recipe for adding OOP to
JavaScript: the Type class. Among other things, the Type class implements methods
for registering classes and namespaces so they can be reflected on at run-time. Its
registerClass method makes a class eligible for run-time discovery and allows the
registrar to specify a base class. Furthermore, Type defines an initializeBase method
that a “derived” class can call in its constructor to initialize the base class, as well as
a callBaseMethod for invoking methods in the base class. You can read all about Type
at http://ajax.asp.net/docs/ClientReference/Global/TypeClass/default.aspx and view
its source code in MicrosoftAjax.js. It is arguably the most important class in the entire
client framework.
An example will help paint a picture of how Type is combined with functions and
prototypes to add OOP-like behavior to JavaScript. The JavaScript in Figure 3-6 uses
Type.registerNamespace to register a namespace named Custom. Then it adds a class
named Person to the namespace. At the end, a call to the registerClass method added
to the Person class through Type.prototype registers the Person class with the
Microsoft AJAX Library.

Figure 3-6: Implementing a Person class


Type.registerNamespace("Custom");

Custom.Person = function(name)
{
this._name = name;
}

Custom.Person.prototype =
{
get_name: function() { return this._name; }
}

Custom.Person.registerClass('Custom.Person');

Once the Person class is defined in this manner, it can be exercised with the following
JavaScript code:

var p = new Custom.Person('Jeff');

// Displays "Jeff"
window.alert(p.get_name());

// Displays "Custom.Person"
window.alert(Object.getTypeName(p));

Note the use of Object.getTypeName, which is one of the JavaScript base type
extensions mentioned in Section 3.1.

What if you wanted to derive from Person to create a Programmer class? Type helps
make that possible, too. Figure 3-7 shows how such a class might be implemented.
Note the call to initializeBase in the constructor, and the base class (Custom.Person)
specified in the registerClass method’s second parameter. Also note the call to
callBaseMethod in get_name to invoke the same method in the base class.

Figure 3-7: Deriving from the Person class


Custom.Programmer = function(name, language)
{
Custom.Programmer.initializeBase(this, [name]);
this._language = language;
}

Custom.Programmer.prototype =
{
get_name: function()
{
var name = Custom.Programmer.callBaseMethod (this,
'get_name');
return name + ' (Programmer)';
},

get_language: function()
{
return this._language;
}
}

Custom.Programmer.registerClass ('Custom.Programmer',
Custom.Person);

The following JavaScript code creates a Programmer object and puts it through its
paces:

var p = new Custom.Programmer('Jeff', 'C#');

// Displays "Jeff (Programmer)"


window.alert(p.get_name());

// Displays "C#"
window.alert(p.get_language());

// Displays "Wintellect.Programmer"
window.alert(Object.getTypeName(p));

Everything behaves as you would expect, including the call to Object.getTypeName,


which returns the name of the derived class rather than of the base class.

3.4 Script Core Library


MicrosoftAjax.js contains the Script Core Library, which forms the nucleus of the
Microsoft AJAX Library. This is where the JavaScript base type extensions described in
Section 3.1, the global functions discussed in Section 3.2, and the Type class described
in the Section 3.3 are implemented. It’s also where the core networking infrastructure
used to perform asynchronous callbacks to servers and serialize and deserialize JSON
data is located. In short, the Script Core Library contains everything that the rest of
the Microsoft AJAX Library has to have in order to run.

The Script Core Library implements approximately 25 classes grouped into the five
namespaces listed in Figure 3-8. Some, like StringBuilder, are utility classes. Others,
such as JavaScriptSerializer and WebRequest, are fundamental to the operation of the
ASP.NET AJAX framework. The following code uses Sys.Net.WebRequest to launch an
asynchronous XML-HTTP request and resembles plumbing deep inside the Microsoft
AJAX Library that does the same:

var request = new Sys.Net.WebRequest();


request.set_url("AjaxDemo.aspx?mode=callback");
request.add_completed
(Function.createDelegate(this, onCallbackCompleted));
request.invoke();
...
function onCallbackCompleted(response, args)
{
if (response.get_statusCode() == 200)
window.alert(response.get_responseData());
}

Under the hood, WebRequest.invoke delegates to


WebRequestManager.executeRequest, which in turn delegates to an “executor.” The
default executor is Sys.Net.XMLHttpExecutor, whose own executeRequest method is
the launch pad for asynchronous XML-HTTP requests in ASP.NET AJAX.

Figure 3-8: Key Script Core Library classes and namespaces


Namespace Key Classes
Sys StringBuilder, Component, CultureInfo, _Application, _Debug
Sys.UI DomEvent, DomElement, Behavior, Control
Sys.Net _WebRequestManager, WebRequestExecutor, WebRequest,
XMLHttpExecutor
Sys.Serialization JavaScriptSerializer
Sys.Services _AuthenticationService, _ProfileService, ProfileGroup

3.5 Base Class Library


The Script Core Library is supplemented by a larger and richer set of JavaScript classes
that comprise the Base Class Library, or BCL. The majority of the roughly 100 classes
in the BCL are implemented in PreviewScript.js, but some live in PreviewGlitz.js,
PreviewDragDrop.js, and MicrosoftAjaxWebForms.js. As such, most of the BCL is
available only if you install the ASP.NET AJAX Futures CTP—the only exception being
the classes in MicrosoftAjaxWebForms.js.

Figure 3-9 lists some of the key classes and namespaces in the BCL. One of the most
important is the PageRequestManager class, which is the client half of the
UpdatePanel control and is discussed in greater detail in the next section. The classes
in the Sys.Preview.UI namespace (and its children) abstract HTML DOM elements and
open the door to animations, transparencies, drag-and-drop, client-side rendering of
server data, and other visual effects. A handful of these capabilities are accessible
through server controls (for example, the DragOverlayExtender control emits code
that wraps instances of Sys.Preview.UI.FloatingBehavior around DOM elements), but in
general, you have to write JavaScript that runs on the client to tap into the full power
of Sys.Preview.UI. Some of its features can, however, be leveraged using server
controls in the ASP.NET AJAX Control Toolkit.

Figure 3-9: Key Base Class Library classes and namespaces


Namespace Key Classes
Sys.Preview Binding, Action, InvokeMethodAction,
SetPropertyAction, Counter, Timer
Sys.Preview.Data DataColumn, DataRow, DataTable, DataView,
DataSource
Sys.Preview.UI Button, CheckBox, HyperLink, Image, Label,
Selector, TextBox, _DragDropManager,
FloatingBehavior, DragDropList
Sys.Preview.UI.Data ListView, ItemView, DataControl
Sys.Preview.UI.Effects OpacityBehavior, LayoutBehavior, Animation
Sys.WebForms PageRequestManager

To have some fun with the BCL (and see what it’s like to program it directly), try
inserting the following <script> block into an ASP.NET AJAX page that contains an
image whose ID is “SplashImage”:

<script type="text/javascript">
function pageLoad()
{
var image = new Sys.Preview.UI.Image ($get('SplashImage'));
var fade = new Sys.Preview.UI.Effects.FadeAnimation();
fade.set_target(image);
fade.set_effect (Sys.Preview.UI.Effects.FadeEffect.FadeIn);
fade.set_duration(3);
fade.set_fps(20);
fade.play();
}
</script>

For this code sample to work, you’ll need to download PreviewGlitz.js to the page.
Here’s how to download it with a ScriptManager (or ScriptManagerProxy) control:

<asp:ScriptManager ID="ScriptManager1" runat="server">


<Scripts>
<asp:ScriptReference Name="PreviewGlitz.js"
Assembly="System.Web.Preview" />
</Scripts>
</asp:ScriptManager>

Now display the page in your browser and watch the image.
Sections 3.6 and 3.7 provide additional information about selected BCL classes. The
ASP.NET AJAX Web site contains a detailed reference to them all at
http://ajax.asp.net/docs/ClientReference/default.aspx.

3.6 PageRequestManager
One BCL class that deserves special mention is Sys.WebForms.PageRequestManager,
which is implemented in MicrosoftAjaxWebForms.js and provides client support for
partial-page rendering. The UpdatePanel control facilitates partial-page rendering on
the server, but the PageRequestManager class, which is the client-side counterpart to
UpdatePanel, facilitates it on the client.

When you set EnablePartialRendering to true in a ScriptManager control,


ScriptManager emits markup that creates and initializes a PageRequestManager
object. PageRequestManager manages the asynchronous callbacks transmitted to the
server to update UpdatePanel controls, and it provides the logic on the client that
replaces the old content in an UpdatePanel control with fresh content after an
update.

PageRequestManager also exposes a JavaScript API. Methods such as abortPostBack


enable asynchronous updates to be canceled in progress, while getInstance retrieves a
reference to the page’s PageRequestManager object. (For an example in which both
methods are used, refer to Figure 2-8.) PageRequestManager also raises life-cycle
events in the browser that indicate when updates have occurred or are about to occur.
Arguably the most important of these events is pageLoaded, which fires each time the
page is refreshed following an asynchronous callback or a synchronous postback.

Normally, PageRequestManager works quietly behind the scenes in support of


UpdatePanel controls, and most developers don’t even realize it’s there. But one very
practical reason to program PageRequestManager directly is to implement “update
highlighting.” Because UpdatePanel updates are clean and flicker-free, some Microsoft
customers have requested a means for highlighting UpdatePanel controls that have
undergone updates in order to draw the user’s attention to the updated content.

Figure 3-10 shows one way to implement such a feature. When the page loads,
JavaScript code registers an event handler for PageRequestManager’s pageLoaded
event. The args parameter passed to the event handler is a PageLoadedEventArgs
object, which has a get_panelsUpdated method that identifies the UpdatePanel
controls that were just updated. The event handler enumerates updated UpdatePanel
controls and calls a local helper function named flashPanels to flash each UpdatePanel
on and off three times.

Figure 3-10: Highlighting updated UpdatePanel controls


<script type="text/javascript">

var prm = Sys.WebForms.PageRequestManager.getInstance();


prm.add_pageLoaded(pageLoaded);

var _panels, _count;


function pageLoaded(sender, args)
{
if (_panels != undefined && _panels.length > 0)
{
for (i=0; i < _panels.length; i++)
_panels[i].dispose();
}

var panels = args.get_panelsUpdated();

if (panels.length > 0)
{
_panels = new Array(panels.length);

for (i=0; i < panels.length; i++)


_panels[i] = new Sys.UI.Control(panels[i]);

flashPanels(3);
}
}

function flashPanels(count)
{
_count = (count << 1) + 1;

for (i=0; i < _panels.length; i++)


_panels[i].set_visible(false);

window.setTimeout(toggleVisibility, 50);
}

function toggleVisibility()
{
for (i=0; i < _panels.length; i++)
_panels[i].set_visible(!_panels[i].get_visible());

if (--_count > 0)
window.setTimeout(toggleVisibility, 50);
}
</script>

3.7 HTML Controls


Among the many classes in the Microsoft AJAX Library BCL are the control classes
found in the Sys.Preview.UI namespace. These classes wrap HTML elements such as
<input> and <select>. They are implemented in PreviewScript.js and are therefore
available only if you elect to use the ASP.NET AJAX Futures CTP.

Figure 3-11 lists some of the control classes featured in PreviewScript.js. Not shown
are validator controls such as RequiredFieldValidator and RegexValidator, which serve
the same purpose in Microsoft AJAX Library applications that ASP.NET validator
controls do in ASP.NET applications. Remember also that the Microsoft AJAX Library
includes a Sys.Preview.UI.Data namespace featuring a very rich set of data controls
with names such as ListView and ItemView. Though beyond the scope this document,
the data controls enable client-side data binding to data sources on the server in the
same way that GridView, DetailsView, and other ASP.NET server controls facilitate
rich server-side data binding.

Figure 3-11: HTML control classes in PreviewScript.js


Class Description
Button HTML button controls (e.g., <input type=“button”> elements)
CheckBox HTML check box controls (e.g., <input type=“checkbox”>
elements)
HyperLink HTML hyperlinks (e.g., <a> elements)
Image HTML images (<img> elements)
Label HTML label controls (<span> elements)
Selector HTML selector controls (<select> elements)
TextBox HTML text box controls (e.g., <input type=“text”> elements)

All the classes in Figure 3-11 derive either directly or indirectly the Sys.UI.Control
class found in the Script Core Library. As such, they inherit a common set of features.
Among those features are get_visible and set_visible methods for controlling visibility
in a browser-independent way, a get_element method for accessing underlying DOM
elements, and the ability to bubble DOM events.

Figure 3-12 contains selected portions of a DHTML page that implements an interactive
UI driven entirely from the client. The UI consists of a text box, a button, and an
empty <span> element. When the button is clicked, the onClick function uses the
browser DOM to read the contents of the text box and display it to the right of the
button by assigning it to the <span> element’s innerHTML property. As a result, what
the user types into the text box is echoed to the page when the button is clicked.

Figure 3-12: Simple DHTML page


<input type="text" id="Input" />&nbsp;
<input type="button" id="MyButton" value="Click Me"
onclick="onClick();" />&nbsp;
<span id="Output" />

<script type="text/javascript">
function onClick()
{
document.getElementById('Output').innerHTML =
document.getElementById('Input').value;
}
</script>
Figure 3-13 contains the equivalent page written with Microsoft AJAX Library HTML
controls. The JavaScript code contains a pageLoad function that wraps TextBox,
Button, and Label controls around the corresponding DOM elements. It also registers a
handler for the Button control’s click events. (If present in an ASP.NET AJAX Web
page, a pageLoad function is automatically called after the page loads and the library
is initialized.) The handler echoes the user’s input to the page by reading it from the
TextBox control and writing it to the Label control. Note that the JavaScript code
never accesses the browser DOM directly; instead, it accesses it indirectly by
interacting with the controls that wrap the DOM elements.

Figure 3-13: Using the HTML control classes from JavaScript


<input type="text" id="Input" />&nbsp;
<input type="button" id="MyButton" value="Click Me" />&nbsp;
<span id="Output" />

<script type="text/javascript">
var g_textBox;
var g_label;

function pageLoad()
{
g_textBox = new Sys.Preview.UI.TextBox($get('Input'));
var button = new Sys.Preview.UI.Button($get('MyButton'));
g_label = new Sys.Preview.UI.Label($get('Output'));
button.initialize();
button.add_click(onClick);
}

function onClick()
{
g_label.set_text(g_textBox.get_text());
}
</script>

Are there advantages to writing JavaScript his way? Yes—in fact, there are two. One,
the same code works not just in Internet Explorer, but in Firefox and Safari and all the
other browsers that ASP.NET AJAX supports. Rather than devote time to testing and
tweaking the code to work in different browsers, you can let Microsoft sweat those
details for you. Two, the control classes simplify certain tasks involving HTML controls.
Rather than iterate through the items in a <select> element to find the one you wish
to select, for example, you can call Selector.set_selectedValue to select the item.

3.8 xml-script
The Microsoft AJAX Library can be programmed imperatively using JavaScript. It can
also be programmed declaratively using a language known as xml-script.
Support for xml-script is found in PreviewScript.js, which is part of the ASP.NET AJAX
Futures CTP. xml-script played a huge role in pre-Beta releases of ASP.NET AJAX, then
known by the code name “Atlas.” (In early releases, ASP.NET AJAX server controls
rendered xml-script instead of JavaScript.) Its role is greatly diminished today, and in
fact it doesn’t have to be used at all. But certain tasks in the Microsoft AJAX Library—
especially ones that involve templated controls such as Sys.Preview.UI.Data.ListView—
are implemented more easily in xml-script than in JavaScript. Therefore, xml-script is
a feature that ASP.NET AJAX developers should at least be aware of, whether they
choose to use it or not.

Figure 3-14 shows the xml-script version of the page in Figure 3-13. The pages are
identical on the outside, but very different on the inside. Elements such as <textBox>
and <button> in xml-script declare instances of TextBox and Button controls and link
them to DOM elements. The <click> element inside the <button> element registers a
handler for click events, and the <invokeMethodAction> element inside the <click>
element invokes a method named evaluateIn on an object named “TextBinding” when
a click event is raised. What is “TextBinding?” It’s a Binding object (an instance of
System.Preview.Binding) created with a <binding> element. It binds the text property
of the TextBox control to the text property of the Label control. When the binding is
evaluated (that is, when its evaluateIn method is called), the contents of the TextBox
control are copied to the Label control.

Figure 3-14: Using the HTML control classes from xml-script


<input type="text" id="Input" />&nbsp;
<input type="button" id="MyButton" value="Click Me" />&nbsp;
<span id="Output" />

<script type="text/xml-script">
<page
xmlns:script="http://schemas.microsoft.com/xml-script/2005">
<components>
<textBox id="Input" />
<button id="MyButton">
<click>
<invokeMethodAction target="TextBinding"
method="evaluateIn" />
</click>
</button>
<label id="Output">
<bindings>
<binding id="TextBinding" dataContext="Input"
dataPath="text" property="text" automatic="false" />
</bindings>
</label>
</components>
</page>
</script>
This is a very different way of exercising the Microsoft AJAX Library, and the jury is
still out on what role, if any, xml-script will play in future versions of ASP.NET AJAX.
On the negative side, there are currently no tools to support it (no special editors or
IntelliSense engines, for example). It imposes extra overhead on the client due to XML
parsing, it’s difficult to debug, and there’s precious little documentation describing it.
On the positive side, with the proper tool support, writing xml-script could be easier
than writing JavaScript, and an XML scripting language brings to mind some enticing
possibilities involving XAML.
4.0 Summary
AJAX has gained widespread popularity in recent years as a means for making Web
applications richer and more interactive—in short, to make them feel less like Web
applications and more like rich clients. ASP.NET AJAX is an AJAX framework that
abstracts and simplifies AJAX. With it, developers who know little about JavaScript,
XML-HTTP, and other pillars of AJAX can write AJAX-enabled applications and get
them to market in a timely fashion.

ASP.NET AJAX shortens the development cycle by providing high-level AJAX wrappers
such as UpdatePanel controls on the server and a rich library of JavaScript types and
extensions on the client. The server half of the platform, the ASP.NET 2.0 AJAX
Extensions, transforms ASP.NET 2.0 into a great platform for AJAX applications. The
client half, the Microsoft AJAX Library, makes browsers a richer and more productive
environment in which to work and offers not only browser independence, but
independence from the server platform as well.

Vous aimerez peut-être aussi