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.

ASP.net AJAX for Developers

Embed Size (px)

DESCRIPTION

ASP.NET AJAX for DevelopersInformation 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 i

Citation preview

Page 1: ASP.net AJAX for Developers

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.

Page 2: ASP.net AJAX for Developers

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

Page 3: ASP.net AJAX for Developers

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

Page 4: ASP.net AJAX for Developers

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.

Page 5: ASP.net AJAX for Developers

• 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

Page 6: ASP.net AJAX for Developers

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); }

Page 7: ASP.net AJAX for Developers

} 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

Page 8: ASP.net AJAX for Developers

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

Page 9: ASP.net AJAX for Developers

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.

Page 10: ASP.net AJAX for Developers

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

Feature ASP.NET AJAX 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 ●

Page 11: ASP.net AJAX for Developers

Client

Feature ASP.NET AJAX 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.

Page 12: ASP.net AJAX for Developers

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.

Page 13: ASP.net AJAX for Developers

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"

Page 14: ASP.net AJAX for Developers

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

Page 15: ASP.net AJAX for Developers

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

Page 16: ASP.net AJAX for Developers

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:

Page 17: ASP.net AJAX for Developers

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

Page 18: ASP.net AJAX for Developers

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>

Page 19: ASP.net AJAX for Developers

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

Page 20: ASP.net AJAX for Developers

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

Page 21: ASP.net AJAX for Developers

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:

Page 22: ASP.net AJAX for Developers

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.

Page 23: ASP.net AJAX for Developers

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.

Page 24: ASP.net AJAX for Developers

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

Page 25: ASP.net AJAX for Developers

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:

Page 26: ASP.net AJAX for Developers

<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.

Page 27: ASP.net AJAX for Developers

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 {

Page 28: ASP.net AJAX for Developers

[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

Page 29: ASP.net AJAX for Developers

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

Page 30: ASP.net AJAX for Developers

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>

Page 31: ASP.net AJAX for Developers

</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'); }

Page 32: ASP.net AJAX for Developers

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.

Page 33: ASP.net AJAX for Developers

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.

Page 34: ASP.net AJAX for Developers

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.aspx. 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

Page 35: ASP.net AJAX for Developers

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.

Page 36: ASP.net AJAX for Developers

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.

Page 37: ASP.net AJAX for Developers

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;

Page 38: ASP.net AJAX for Developers

} 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

Page 39: ASP.net AJAX for Developers

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

Page 40: ASP.net AJAX for Developers

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.

Page 41: ASP.net AJAX for Developers

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;

Page 42: ASP.net AJAX for Developers

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

Page 43: ASP.net AJAX for Developers

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>

Page 44: ASP.net AJAX for Developers

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.

Page 45: ASP.net AJAX for Developers

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>

Page 46: ASP.net AJAX for Developers

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.

Page 47: ASP.net AJAX for Developers

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.