Cutting Edge

Perspectives on ASP.NET AJAX

Dino Esposito

Contents

Ways to AJAX in ASP.NET
The Straight Way to ASP.NET AJAX
UpdatePanel and the Interceptor Pattern
Taking Control of Out-of-Band Calls
Page Methods vs. Web Service Methods
My Way to ASP.NET AJAX

Unless you've spent the past 12 months disconnected from the Net-perhaps vacationing on a remote tropical island or participating in a reality game show-you should know a few things about AJAX. But I'll do a quick refresher just in case.

First, there's the acronym-it stands for Asynchronous JavaScript and XML. Then there is its purpose: a true breakthrough, AJAX makes possible solutions that would be otherwise impossible or just impractical to obtain. And finally, you should understand what AJAX is made up of. It's not a technology, per se. Instead, it is a blanket term to indicate rich browser applications built using powerful combinations of client-side Web technologies that have been around for years, such as JavaScript, cascading style sheets (CSS), DHTML, and XMLHttpRequest.

A large share of the browsers currently available support a common set of features-and these features allow Web developers to build applications that are very interactive, able to refresh quickly, and capable of doing a good deal of work on the client. Leveraging theses capabilities, AJAX applications provide rich user experiences that are similar to using desktop applications. Furthermore, AJAX makes it easier than ever to create "mash-up" applications. A mash-up is simply a Web application that combines information from multiple sources (for example, bringing together Microsoft® Virtual Earth™ with property sales information to create a helpful real estate tool).

I actually think that AJAX is so big, so important, that it will be forgotten in the next year or so. What? This is because I think AJAX will be absorbed by everybody in the industry, becoming a standard part of everyday life that we just don't think about-like today you don't feel the need to emphasize the use of XML or HTTP.

Unveiled at the Microsoft Professional Developers Conference in September 2005, Microsoft ASP.NET AJAX (formerly referred to as "Atlas") adds many new capabilities to ASP.NET 2.0 (see asp.net/ajax), all of which are geared towards making it easy to add AJAX-based functionality to your Web sites. In this month's column, I examine ASP.NET AJAX, looking closely at some of its key features. This column assumes you have at least some degree of familiarity with the basic concepts and tools. For a good introduction, see the article "Atlas at Last: ASP.NET Atlas Powers the AJAX-Style Sites You've Been Waiting For" by Matt Gibbs in the July 2006 issue of MSDN®Magazine. Also, see the sidebar "Still Synchronous for Now" for some additional information.

Ways to AJAX in ASP.NET

What new application functions can you build with AJAX? More specifically, what functions can you build using asynchronous JavaScript calls and the browser's object model? There are three main technologies that enable AJAX functionality: remote method calls, client-side data binding, and visual effects. Remote method calls sounds a bit too vague, so I'll narrow this to partial page postbacks and out-of-band requests.

How do you turn your new or existing ASP.NET apps into AJAX applications? It has been reported that more than 100 frameworks for AJAX development exist today-they support a variety of platforms and utilize a number of programming approaches. In general, I tend to group AJAX frameworks into three main categories based on their capabilities: callback frameworks, UI frameworks, and full frameworks.

A callback framework consists of a simple set of client and server libraries. It doesn't let you do much more than invoke a piece of server-side code from the client, moving input and output parameters in a serialized format. A typical UI framework is the evolution of an existing professional control library that provides advanced grid, charting, and tree controls. These support asynchronous postbacks and injecting JavaScript code on the client for automatic page refreshes. Finally, a full framework provides a rich programming model that includes controls and application services, preferably on both the client and the server. Microsoft ASP.NET AJAX falls into this third category.

If you already use a commercial suite of controls, upgrading to the next AJAX-powered version will likely be a seamless experience. If you develop applications entirely in-house and take care of the presentation layer as well as the back-end layers, then a full framework is the most viable option. Finally, a simple framework is useful only to add quick callback capabilities to existing ASP.NET applications, for both version 1.1 and 2.0.

ASP.NET 2.0 already provides a built-in script callback API, which I've written about in this column several times, for instance "Cutting Edge: Script Callbacks in ASP.NET" and "Cutting Edge: Custom Script Callbacks in ASP.NET"). And in the companion code for this column, I've included a demo of an extremely simple AJAX framework for remote method calls. It uses just 50 lines of code, part in JavaScript and part in managed code. Obviously, it can't compete with ASP.NET AJAX, but it can be used as the core code to add basic AJAX capabilities to ASP.NET 1.1 applications.

The Straight Way to ASP.NET AJAX

ASP.NET AJAX is composed of two distinct, though not mutually exclusive, APIs: client and server. You can build AJAX functionalities using direct client-side programming, traditional server-side programming, or any combination of the two. Any AJAX-based page inherently requires some client-side JavaScript code to address the browser's document object model (DOM) and any application-specific extension. It isn't necessary, however, to leave the writing of such a script code up to the ASP.NET programmer. A framework, in fact, could generate made-to-measure script code as the output of a server-side control. This form of indirect page updating is by far the simplest way to add AJAX capabilities to new and existing ASP.NET 2.0 pages. In ASP.NET AJAX, page updates can be governed by a piece of client code automatically injected by a server control-the UpdatePanel control.

The UpdatePanel control represents the nerve center of the server-centric programming model of ASP.NET AJAX. It lets you execute server-side code and return updated markup to the client browser. You may wonder how this differs from classic postbacks. The difference is in how the postback is implemented-instead of a full page refresh, the UpdatePanel control manages to send an out-of-band request for fresh markup and then update the DOM tree when the response is ready.

The client-centric programming model of ASP.NET is centered around the ability of placing calls to remote endpoints (mostly, but not exclusively, ASP.NET Web services and Windows® Communication Foundation services). When initiated straight from the client browser, a call to a remote endpoint requires a JavaScript proxy and a pinch of JavaScript code. Finally, client-side data binding can be viewed as an extension to the classic JavaScript runtime and DOM. In a purely client-side programming style, you connect to a remote endpoint, download data, and bind it to a DOM subtree. The structure of the template remains on the client, along with some state information, and only raw data is moved from the server to the client.

There are three main approaches to programming in ASP.NET AJAX. Figure 1 outlines these tools and tells you when they are most appropriate to use.

Figure 1 Approaches to Programming in ASP.NET AJAX

Approach Description Use
UpdatePanel Contains a group of server controls and monitors their postbacks and rendering process. Any requests for postback that originate from the contained controls are hijacked and served via script. Changes to the page are applied using DHTML. Used when your team lacks significant JavaScript skills or you simply prefer to minimize the exposure to client-side programming. The use of UpdatePanel is also recommended when you need to protect any sensitive business logic in your app.
Remote method calls Blanket term for asynchronous calls to page methods and local and external Web services. Calls move input arguments and receive return values via JSON streams in a type-independent manner. Strongly typed JavaScript code is required to trigger the call and apply changes back on the client. Used when you need to work with a smarter client that triggers and controls remote operations in an asynchronous manner. This approach requires JavaScript coding to process return values and update any portion of the current DOM that is affected by results.
Client-side data?binding* Two client-side controls written entirely in AJAX JavaScript to implement template-based binding. They are ListView, for multiple-records view, and ItemView, for single-record view. These two controls are combined together with client data source and filtering components. Used when you need a more modern and cross-browser version of DHTML applications. With client-side data binding, your final pages include a thick layer of JavaScript and/or XML Script and virtually no managed code except for the Script Manager control.

UpdatePanel and the Interceptor Pattern

The UpdatePanel control heralds a programming style where page contents update without complete page refreshes and without a need for client-side programming. In ASP.NET AJAX lingo, this is referred to as partial rendering. The UpdatePanel control is the most visible component involved in enabling this capability. However, the real brains behind the internal implementation of partial rendering is the ScriptManager control. Still, the UpdatePanel control is the main tool developers use when writing pages that are partially updatable.

A Web page refresh can be obtained in either of two ways-manually clicking on a Submit button or programmatically calling into the submit method of the DOM form object. In both cases, the browser freezes the current page and sends a new request to the back-end Web server. The incoming response then overrides the existing contents.

The purpose of the UpdatePanel control is simply to hook up this process. It intercepts form submissions, captures any information being sent, and sends the same information through an out-of-band call based on XMLHttpRequest. The UpdatePanel control also adds some extra information to indicate which selection of controls are to be processed and rendered on the server-partial page rendering.

The behavior that results out of the UpdatePanel control is fully described by the interceptor pattern. The pattern refers to any external component that observes an object call and injects its own code between the caller and the receiver. In this way, the external component takes full control of the operation, controls how the task is accomplished, and returns a valid response to the caller. Figure 2 illustrates the implementation of this pattern in ASP.NET AJAX.

Figure 2 UpdatePanel Control and the Interceptor Pattern

Figure 2** UpdatePanel Control and the Interceptor Pattern **(Click the image for a larger view)

The script code that is injected into the client page registers a handler for the form's onsubmit DOM event. This new handler simply replaces the classic request with one that goes through XMLHttpRequest and passes extra information. In particular, it adds the name of the UpdatePanel control responsible for the postback to the existing list of input fields. The modified contents for a page with a pageable grid look like this:

ScriptManager1=UpdatePanel1|GridView1& __EVENTTARGET=GridView1& __EVENTARGUMENT=Page%241& __VIEWSTATE=...& __VIEWSTATEENCRYPTED=& __EVENTVALIDATION=...

The ScriptManager pseudo parameter refers to the ID of the UpdatePanel control that is responsible for the postback. Only the controls associated with the specified UpdatePanel control will be refreshed and their modified markup sent back to the browser, along with updated viewstate information.

Partial rendering is a common feature in various AJAX frameworks, although the internal implementations vary. Most of the differences have to do with the approach used to associate updatable controls with the request. In ASP.NET AJAX, updatable controls are grouped in an outermost container control (the UpdatePanel). Everything inside the container is rendered out to markup-this represents the delta of the currently displayed page. One alternative approach is to require that individual controls register programmatically with the framework for rendering over AJAX-style postbacks. This is more or less what happens in ASP.NET 2.0 with controls that support control state.

A more granular, more flexible approach than grouping controls in a container is to have each individual control decide how it renders AJAX-style postbacks. However, you'll also need additional codebehind instructions or ad hoc controls should be used. While good for control libraries and other such products, this approach is far too intrusive for a Web framework such as ASP.NET.

The UpdatePanel control is a class that's derived from System.Web.UI.Panel. A UI-free container of child ASP.NET controls, UpdatePanel can contain any ASP.NET server controls and doesn't require you to use any special AJAX-enabled controls. By using UpdatePanel, AJAX programming is done entirely on the server using the same application model and programming style as classic ASP.NET. Developers don't need to learn about JavaScript or the client-side Microsoft AJAX Library. Likewise, they have no exposure to XML Script or the browser's DOM.

Transforming a traditional ASP.NET page into an AJAX page is a two-step operation. First, you add a ScriptManager control to the page. You then wrap any group of controls that you want to refresh partially and asynchronously with an UpdatePanel control. The UpdatePanel control supports nesting scenarios and can be created dynamically, and an ASP.NET page can contain as many UpdatePanel controls as you want.

The actual update is triggered in two possible ways: when child controls post back and when specific external events occur. Through triggers and other properties you can make each UpdatePanel control refresh its contents conditionally.

With the UpdatePanel control, you can migrate ASP.NET pages to AJAX piecemeal and do so very quickly. The same ASP.NET page, in fact, can fire both AJAX-style and classic postbacks. For this reason, UpdatePanel must move the view state of the page with each and every request. In particular, the view state is sent to the server, updated to reflect changes on selected controls, and then downloaded to the client. The same happens to event validation data. View state and event validation data cannot be updated on the client and for this reason must be sent back to the server, checked for tampering, and properly updated. Having up-to-date copies of the view state and event validation data available on the client is key to maintaining the page in a consistent state while allowing successful postbacks, in both AJAX and classic styles.

Ultimately, UpdatePanel is the easiest approach to learn for ASP.NET AJAX, it involves the least possible upgrade and migration work, and it is fully interoperable between classic and AJAX pages. When you use updatable panels, pages refresh more quickly. In fact, these updates are sometimes too fast for users to note the changes. For this reason, a busy panel that tells what's going on may not be enough. A busy panel like the UpdateProgress control is designed for long tasks-not to give users feedback on displayed changes. A better tool for giving users feedback on such changes is the UpdatePanelAnimation extender, which is defined in the latest CTP of the AJAX Control Toolkit. You can see a sample of this in action. The extender animates the area covered by UpdatePanel during the postback. In particular, you can specify animations for the updating and updated events on the extender. Note, though, that you have to install the AJAX Control Toolkit separately, as it is not incorporated in the ASP.NET AJAX Extensions download.

Taking Control of Out-of-Band Calls

If you're comfortable with JavaScript and want to try making direct server calls from the client, you have two main options: using Web services and calling into static page methods.

By registering an ASMX Web service with the script manager, you instruct the ASP.NET AJAX infrastructure to generate a JavaScript proxy class and inject it into the client page. You can take a look at the proxy class by typing the URL of the Web service into the address bar (local machine) followed by the /js suffix. Here's an example of a JavaScript proxy for a Web service with two public methods. The code has been simplified for reading:

Type.registerNamespace('Samples.MyWebService'); Samples.MyWebService = new function() { this.appPath = "https://YourServer/AjaxDemo/"; var cm = Sys.Net.ServiceMethod.createProxyMethod; cm(this, "LookupCustomer", "id"); cm(this, "LookupAllCustomers"); }

This code makes it possible for you to call the Web service from a script tag. It uses the classic Proxy pattern, and the overall mechanism is exactly the same as when you're using Web services on the server in classic ASP.NET or in Windows applications.

There are some caveats, though. What kind of server-side code would you call from a client? Or, put another way, what kind of operations do you expect to be invoked from the client on Web services? Web services that are invoked from AJAX pages expose some business logic to the client pages. A public endpoint, a Web service can be invoked from the Internet and there's no built-in security layer to protect your application logic. This vulnerability is nothing new.

ASP.NET AJAX gives developers a chance to expose some application logic through Web services. Once published on the Internet, this logic (not protected by any security layer) is available to any callers. In general, you should only expose data and logic that is considered safe for Internet use. There might be no real problem if you write and invoke a Web service that returns a products catalog. However, exposing the business logic layer (BLL), including, for example, the credit card verification process, is not something you should do.

ASP.NET AJAX leads you to use Web services to expose BLL to client pages for direct use. You should think of AJAX Web services as a sort of non-critical, user interface layer BLL. Any truly sensitive pieces of BLL should be invoked using classic postbacks or UpdatePanel controls.

To link Web services directly to an ASP.NET AJAX page, they must be local Web services hosted in the same Web application as the caller page. There are two main reasons for this requirement. First, the Web service must be backed by an ASP.NET AJAX application that knows how to handle the /js suffix appended to each request. You could, however, use another ASP.NET AJAX application to host the Web service. In this case, your client calls might clash with the stricter security settings in recent browsers that prevent cross-site calls.

Page Methods vs. Web Service Methods

Another possible approach to binding server code to ASP.NET AJAX pages is to invoke page methods. A callable page method is a public static (or Shared in Visual Basic® .NET) method defined in the codebehind class and decorated with the same WebMethod attribute used for Web service methods. At present, this is limited to ASPX pages-both inline and codebehind code-but might be extended in the future to user controls and custom controls.

I should note that the ASMX Web services and page methods require different settings. In particular, you must register Web services with the script manager and you must install a script HTTP module to run page methods. Figure 3 shows what's needed in the web.config file.

Figure 3 Changes in Web.config for ASP.NET AJAX

<microsoft.web> <scripting> <webServices> ... </webServices> </scripting> </microsoft.web> <system.web> <httpHandlers> <remove verb="*" path="*.asmx"/> <add verb="*" path="*.asmx" type="Microsoft.Web.Script.Services.ScriptHandlerFactory" validate="false"/> </httpHandlers> <httpModules> <add type="Microsoft.Web.UI.ScriptModule" name="ScriptModule"/> </httpModules> </system.web>

To register a Web service and force the generation of the proxy you need the following:

<asp:ScriptManager ID="scriptManager1" runat="server"> <Services> <asp:ServiceReference Path="~/WebServices/MyDataService.asmx" /> </Services> </asp:ScriptManager>

You'll also need additional attributes to decorate the Web service class. In particular, you need the ScriptService attribute to enable the generation of the JavaScript proxy class and GenerateScriptType for each custom type you plan to use, except for generic types. Figure 4 shows an example.

Figure 4 ASP.NET AJAX Web Service Methods

namespace Samples { [WebService(Namespace = "https://samples.ajax/")] [ScriptService] [GenerateScriptType(typeof(Customer))] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class MyDataService : System.Web.Services.WebService { public MyDataService() {} [WebMethod] public Customer LookupCustomer(string id) { return CustomerManager.Load(id); } [WebMethod] public CustomerCollection LookupAllCustomers() { return CustomerManager.LoadAll(); } }

The GenerateScriptType must be applied for the Customer type, but not for the CustomerCollection if this type is defined to derive from the generic Collection<T> class, for which ASP.NET AJAX has built-in support:

public class CustomerCollection : Collection<Customer> {}

The HTTP module required for page methods hooks up the default HTTP handler for ASPX requests and redirects the rendering stage to a custom piece of code that executes the specified method and serializes return values.

Both the page methods approach and the Web service methods approach help you access the back-end BLL. Like publicly exposed Web service methods, page methods can easily be automated from the address bar of a browser-it only requires some elementary JavaScript Object Notation (JSON) skills. Thus, you should be just as careful with these page methods as with the WebMethods in terms of what BLL logic you expose.

In the end, whether you use page methods or Web service methods is really just a matter of preference. In both cases, you should call into a façade layer that then routes to the proper BLL function, as shown in Figure 5. Web service methods can be called from any page, provided you register the endpoint to the service in each page. Page methods can only be called from the page that defines them. Currently, my personal preference is to use page methods.

Figure 5 Comparison of Page and Web Service Methods

Figure 5** Comparison of Page and Web Service Methods **(Click the image for a larger view)

Both ASP.NET AJAX Web service methods and page methods make extensive use of JSON to pass object data around. A lightweight data-interchange format, JSON is used to serialize objects to strings. Because of its inherent simplicity, JSON is good for both people and machines. More people can write and read JSON strings than can write and read SOAP packets. And JSON is very easy for machines to parse and process.

You might expect page methods to offer better performance than Web services. After all, to resolve Web service calls, the ASP.NET runtime has to parse SOAP packets. This, however, isn't exactly true. ASP.NET AJAX installs a tailor-made HTTP handler (see Figure 3) that intercepts all ASMX requests. Requests with a /js suffix are processed differently, working directly with the JSON payload and Web service method. As a result, no SOAP is involved whatsoever and the body of the request simply contains the JSON stream of input arguments. For non-AJAX requests, the new HTTP handler just delegates the call back to the original ASP.NET handler that understands SOAP.

My Way to ASP.NET AJAX

All things considered, I think UpdatePanel is the best approach for the majority of development teams. It doesn't preclude classic ASP.NET and allows you to modify existing pages at your convenience. Also, it's unobtrusive and doesn't require you to learn many new things before starting. In addition, UpdatePanel gives the same level of protection for your BLL as classic Web pages and it fully supports asynchronous ASP.NET pages running lengthy tasks.

A final piece of advice: avoid mixing various AJAX platforms. In terms of JavaScript built-in object extensions, there might be collisions between ASP.NET AJAX and other frameworks. More importantly, there's no guarantee that a combination of products that works today will still work in the future. Any new version of any framework can introduce new collisions.

Still Synchronous for Now

AJAX functionalities are often associated with asynchronous techniques. Consequently, it is often assumed that ASP.NET AJAX does programming asynchronously by default. This is certainly true from a client perspective—the task starts on the server and the current page remains available for further interaction.

However, ASP.NET AJAX doesn't support ASP.NET 2.0 asynchronous pages, nor does it implement remote calls asynchronously (meaning via asynchronous HTTP handlers). The HTTP handler that serves AJAX Web service requests works synchronously. The same is true for the HTTP module that serves page methods, regardless of whether the ASP.NET page is marked for asynchronous processing. Most of these architectural issues will likely be worked out in a future version of ASP.NET, currently code-named "Orcas." For now, however, the best way out is to implement AJAX through the UpdatePanel control.

Send your questions and comments for Dino to  cutting@microsoft.com.

Dino Esposito is a mentor at Solid Quality Learning and the author of Programming Microsoft ASP.NET 2.0 (Microsoft Press, 2005). Based in Italy, Dino is a frequent speaker at industry events worldwide. Get in touch with Dino at cutting@microsoft.com or weblogs.asp.net/despos.