WEBSITE

The ASP.NET AJAX Infrastructure

10/10/2010 11:14:55 AM
From a developer-oriented perspective, AJAX collectively refers to a set of development components, tools, and techniques for creating highly interactive Web applications that give users an overall better experience. According to the AJAX paradigm, Web applications work by exchanging data rather than pages with the Web server. From a user perspective, this means that faster roundtrips occur and, more importantly, page loading is quicker and the need for refreshing the page entirely is significantly reduced.

As a result, a Web application tends to look like a classic desktop Microsoft Windows application and can invoke server code from the client, run and control server-side asynchronous tasks, and feature a strongly responsive and nonflickering user interface. An AJAX application can have a number of features that minimize user frustration, provide timely feedback about what’s going on, and deliver great mashed-up content. (Hold on! This doesn’t mean AJAX Web applications are the same as desktop applications; they simply allow for a few more desktop-like features.)

Note

AJAX applications have a number of plusses but also a few drawbacks. Overall, choosing an AJAX application rather than a classic Web application is simply a matter of weighing the trade-offs. An AJAX application certainly gives users continuous feedback and never appears held up by some remote operation. On the other hand, AJAX applications are not entirely like desktop applications, and their capabilities in terms of graphics, multimedia, and hardware control are not as powerful as in a regular (smart) client. In the end, AJAX applications are just one very special breed of a Web application; as such, they might require some code refactoring to deliver the expected performance and results.


We are all witnessing and contributing to an interesting and unique phenomenon—the Web is undergoing an epochal change right before our eyes as a result of our actions. Ten years ago, the Web was in its infancy and based on an infrastructure that was simple, ubiquitous, and effective. Ten years of Web evolution has resulted in the building of a thick layer of abstraction on the server side, but it hasn’t changed the basic infrastructure—HTTP protocol and pages. The original infrastructure, which was the chief factor for the rapid success of the Web model of applications, is still there.

In fact, the next generation of Web applications will still be based on the HTTP protocol and pages. However, the contents of pages and the capabilities of the server-side and client-side machinery will change to provide a significantly richer user experience.

The Hidden Engine of AJAX

Today Web applications work by submitting user-filled forms to the Web server and displaying the markup returned by the Web server. The client-to-server communication employs the HTTP protocol and is usually conducted by the browser. The new model that AJAX heralds simply employs an alternate and scriptable tool to conduct the HTTP communication with the Web server. The benefit is that the page that triggers the call remains up and running and refreshes its document object model (DOM) with the freshly downloaded data. No page replacement occurs, and the overall user experience is smooth and continual.

The Classic Browser-Led Model

Using the local Domain Name System (DNS) resolver in the operating system, the browser resolves the requested URL to an IP address and opens a socket. An HTTP packet travels over the wire to the given destination. The packet includes the form and all its fields. The request is captured by the Web server and typically forwarded to an internal module for further processing. At the end of the process, an HTTP response packet is prepared and the return value for the browser is inserted in the body. If the response contains an HTML page, the browser replaces the current contents entirely with the new chunk of markup.

While the request is being processed on the server, the “old” page is frozen but still displayed to the client user. As soon as the “new” page is downloaded, the browser clears the display and renders the page.

This model was just fine in the beginning of the Web age when pages contained little more than formatted text, hyperlinks, and some images. The success of the Web has prompted users to ask for increasingly more powerful features, and it has led developers and designers to create more sophisticated services and graphics. The net effect is that pages are heavy and cumbersome—even though we still insist on calling them “rich” pages. Regardless of whether they’re rich or just cumbersome, these are the Web pages of today’s applications. And nobody really believes that we’re going to return to the scanty and spartan HTML pages of a decade ago.

Given the current architecture of Web applications, each user action requires a complete redraw of the page. Subsequently, richer and heavier pages render slowly and, as a result, produce a good deal of flickering. Projected to the whole set of pages in a large, portal-like application, this mechanism is just perfect for unleashing the frustrations of the poor end user.

The New Out-of-Band Model

The chief factor that enables AJAX functionality in a Web page is the ability to issue out-of-band HTTP requests. In this context, an out-of-band call indicates an HTTP request placed using a component different from the browser. The out-of-band call is triggered via script by an HTML page event and is served by a proxy component. In AJAX frameworks, the proxy component is based on the XMLHttpRequest object.

Note

About a decade ago, there was a team at Microsoft working on a technology called Remote Scripting (RS). RS never reached the stage of a version 1.0 but had a lot in common with today’s AJAX hidden engine. In RS, the proxy component was a Java applet managing the browser-to-server communication.


XMLHttpRequest is a browser’s object that is scriptable through JavaScript. It sends a regular HTTP request to the specified URL and waits, either synchronously or asynchronously, for it to be fully served. When the response data is ready, the proxy invokes a user-defined JavaScript callback to refresh any portion of the page that needs updating. Figure 1 provides a graphical overview of the model.

Figure 1. Out-of-band calls are sent through a proxy component, and a JavaScript callback is used to update any portion of the page affected by returned data


All browsers know how to replace an old page with a new page; until a few years ago, though, not all of them provided an object model to represent the current contents of the page. (Today, I can hardly mention a single modern, commercially available browser that doesn’t expose a read/write page DOM.) For browsers that supply an updatable object model for HTML pages, the JavaScript callback function can refresh specific portions of the old page, thus making them look updated, without a full reload.

Exactly what are the capabilities required of a browser to run AJAX functionalities? As mentioned, a browser needs to provide two key capabilities: a proxy mechanism to make client code able to place out-of-band HTTP calls, and an updatable DOM. And both capabilities must be achieved through standard and globally accepted interfaces.

There’s a World Wide Web Consortium (W3C) ratified standard for the updatable DOM. A W3C standard for the proxy component is currently being developed. It takes the form of the existing XMLHttpRequest object and is devised as an interface exposed by the browser to allow script code to perform HTTP client functionality, such as submitting form data or loading data from a remote Web site. The latest working draft is available at http://www.w3.org/TR/XMLHttpRequest.

In addition, browsers must support JavaScript and, preferably, cascading style sheets (CSS).

The Role of the HTML Document Object Model

The page Document Object Model (DOM) is the specification that defines a platform- and language-neutral interface for accessing and updating the contents, structure, and style of HTML and XML documents. As a recognized standard ratified by the W3C committee, the DOM is now supported by virtually all browsers. The DOM provides a standard set of objects for representing the constituent elements of HTML and XML documents. All together, these objects form a standard interface for accessing and manipulating child elements of HTML pages and, more in general, XML documents.

The DOM application programming interface (API) renders the displayed page as a tree-based structure. For a Web page, each node maps to an object that represents an HTML tag. The object, therefore, has properties and methods that can be applied to an HTML tag. There are three fundamental operations you can accomplish on a node: find the node (including related nodes such as children, parent, or sibling nodes), create a node, and manipulate a node. Identifying a particular node is easy as long as the page author knows the ID of the corresponding element.

The W3C DOM consists of three levels that indicate, for the browser, three different levels of adherence to the standard. For more information, take a look at http://www.w3.org/DOM.

From Dynamic HTML to the Standard DOM

About ten years ago, with Internet Explorer 4.0, Microsoft introduced a proprietary object model named Dynamic HTML (DHTML) to enable page authors to update the current page dynamically using JavaScript. The success of DHTML led to the definition of a standard document object model—the W3C’s DOM. Quite obviously, the DOM evolved from DHTML and became much more generalized than DHTML.

Today most browsers support a mix of DOM and DHTML. Which one should you use? In particular, to update some contents, should you obtain a reference to the textual child node of the node that matches the intended HTML tag (the DOM way) or just grab a reference to a node and use the innerHTML property as you would do in the DHTML way? Likewise, to add a new element, should you create a new element or just stuff in a chunk of updated HTML via innerHTML? Admittedly, one of the most interesting debates in the community is whether to use DHTML to manipulate pages or opt for the cleaner approach propounded by the DOM API.

The key fact is that the DOM API is significantly slower than using innerHTML. If you go through the DOM to generate some user interface dynamically, you have to create every element, append each into the proper container, and then set properties. The alternative only entails that you define the HTML you want and render it into the page using innerHTML. The browser, then, does the rest by rendering your markup into direct graphics.

Overall, DHTML and DOM manipulation are both useful depending on the context. There are many Web sites that discuss performance tests, and DHTML is always the winner. Anyway, DOM is still perfectly fast as long as you use it the right way—that is, create HTML fragments and append them to the proper container only as the final step.

Note

The inclusion of a standard API to edit the currently displayed page is a key factor in the success of AJAX. Although the first working frameworks for AJAX-like remote scripting date back to a decade ago, the limited support that browsers have had for dynamic document changes through most of this time period slowed down the adoption of such technologies in the industry. Until now. With the HTML DOM becoming a widely supported standard and the availability of a mature tool for remote calls such as XMLHttpRequest, AJAX is ready for prime time.


The XMLHttpRequest Object

Created by Microsoft and adopted soon thereafter by Mozilla, the XMLHttpRequest object is fully supported these days by the majority of Web browsers. The implementation can significantly differ from one browser to the next, even though the top-level interface is nearly identical. For this reason, a W3C committee is at work with the goal of precisely documenting a minimum set of interoperable features based on existing implementations. An excellent presentation on the component can be found here: http://developer.mozilla.org/en/docs/XMLHttpRequest.

Note

The XMLHttpRequest object originally shipped as a separate component with Internet Explorer 5.0 back in the spring of 1999. It is a native component of all Microsoft operating systems that have shipped since. In particular, you’ll certainly find it installed on all machines that run Windows 2000, Windows XP, and newer operating systems.


When the XMLHttpRequest object was first released, the Component Object Model (COM) was ruling the world at Microsoft. The extensibility model of products and applications was based on COM and implemented through COM components. In the late 1990s, the right and natural choice was to implement this new component as a reusable automation COM object, named Microsoft.XmlHttp.

COM objects are external components that require explicit permission to run inside of a Web browser. In particular, to run the XMLHttpRequest object, and subsequently enable any AJAX functionality built on top of it, at a minimum a client machine needs to accept ActiveX components marked safe for scripting. (See Figure 2.)

Figure 2. The property window used to change the security settings in Internet Explorer


The XMLHttpRequest object is certainly a safe component, but to enable it users need to decrease their security settings and accept any other component “declared” safe for scripting that is around the Web sites they visit.

Mozilla adopted XMLHttpRequest immediately after its first release with Internet Explorer 5.0. However, in Mozilla-equipped browsers, the XMLHttpRequest object is part of the browser’s object model and doesn’t rely on external components. Put another way, a Mozilla browser such as Firefox publishes its own XMLHttpRequest object into the scripting engine and never uses the COM component, even when the COM component is installed on the client machine and is part of the operating system.

As a result, in Mozilla browsers, XMLHttpRequest looks like a native JavaScript object and can be instantiated through the classic new operator:

// The object name requires XML in capital letters
var proxy = new XMLHttpRequest();

When the browser is Internet Explorer (up to version 6.0), the XMLHttpRequest object is instantiated using the ActiveXObject wrapper, as shown here:

var proxy = new ActiveXObject("Microsoft.XmlHttp");

Generally, AJAX-style frameworks check the current browser and then decide which route to take.

Implemented as a COM component for historical reasons on Internet Explorer browsers, the XMLHttpRequest object has finally become a browser object with Internet Explorer 7.0. All potential security concerns are removed at the root. Needless to say, implemented as a browser object, the XMLHttpRequest functionality is somewhat safer, at least in the sense it doesn’t require users to change their security settings for the browser.

Using the XMLHttpRequest Object

The XMLHttpRequest object is designed to perform one key operation: sending an HTTP request. The request can be sent either synchronously or asynchronously. The following bit of code shows the programming interface of the object as it results from the W3C working draft at the time of this writing:

interface XMLHttpRequest
{
function onreadystatechange;
readonly unsigned short readyState;
void open(string method, string url);
void open(string method, string url, bool async);
void open(string method, string url, bool async, string user);
void open(string method, string url, bool async,
string user, string pswd);
void setRequestHeader(string header, string value);
void send(string data);
void send(Document data);
void abort();
string getAllResponseHeaders();
string getResponseHeader(string header);
string responseText;
Document responseXML;
unsigned short status;
string statusText;
};

Using the component is a two-step operation. First, you open a channel to the URL and specify the method (GET, POST, or other) to use and whether you want the request to execute asynchronously. Next, you set any required header and send the request. If the request is a POST, you pass to the send method the body of the request.

The send method returns immediately in the case of an asynchronous operation. You write an onreadystatechange function to check the status of the current operation and, using that function, figure out when it is done. The following code shows how to carry on a POST request using the XMLHttpRequest object:

var xmlRequest, e;
try
{
xmlRequest = new XMLHttpRequest();
}
catch(e)
{
try
{
xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e)
{
}
}
// Prepare for a synchronous POST request
var body = null; // An empty request body this time...
xmlRequest.open("POST", pageUrl, false);
xmlRequest.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
xmlRequest.send(body);

In a synchronous call, the send method returns when the response has been fully downloaded and parsed by the object. You can access it as a plain string using the responseText property. If the response is an XML stream, you can have it exposed as an XML DOM object using the responseXml property.

Important

If you’re going to use ASP.NET AJAX or any other AJAX-like framework for building your applications, you’ll hardly hear anything about the XMLHttpRequest object, much less use it directly in your own code. An AJAX framework completely encapsulates this object and shields page authors and application designers from it. You don’t need to know about XMLHttpRequest to write great AJAX applications, no matter how complex and sophisticated they are. However, knowing the fundamentals of XMLHttpRequest can lead you to a better and more thorough understanding of the platform and to more effective diagnoses of problems.


The Microsoft AJAX JavaScript Library

Most of the power of AJAX resides on the client and is strictly related to the browser’s and platform’s client-side functionality. No AJAX capability would ever be possible without a client-side engine; and this engine can only be written in JavaScript. Such a script code governs the execution of out-of-band calls and often kicks in and replaces regular postbacks with AJAX postbacks. Moreover, no AJAX functionality would ever be possible without JavaScript and a standard (and rich) DOM. The DOM, though, is not enough.

The DOM represents the programming gateway to the page constituent elements, but it is not designed to provide programming facilities such as those you can find in a general-purpose library. Normally, the script tools you can leverage to consume objects and contents from the DOM are those provided by the JavaScript language. Not exactly a powerful toolkit. Enter the Microsoft AJAX JavaScript library.

The AJAX extensions to ASP.NET silently leverages the Microsoft AJAX JavaScript library for all of its built-in features. The library, though, is also available to page authors to code their own JavaScript page-specific functions.

The Microsoft AJAX library is written in JavaScript, although with a strong sense of object-orientation. The JavaScript language does support objects and allow the creation of custom objects. It does not, however, support full object-orientedness because it has no native concept of true object inheritance. Nonetheless, even excluding true object orientation, JavaScript is still a modern and suitable language that can be used to build a class framework à la the .NET Framework. ASP.NET AJAX takes the JavaScript language to the next level by adding some type-system extensions and the notions of namespace and inheritance. In addition, the ASP.NET AJAX JavaScript supports interfaces and enumerations, and it has a number of helper functions to manipulate strings and arrays.

These extensions are coded using the base set of instructions that characterize the core JavaScript language, and they’re persisted to a set of .js files. These .js files are not installed as distinct files on the Web server when you install ASP.NET. They are embedded as resources into the ASP.NET AJAX assembly—system.web.extensions. If you want them available as distinct files (for example, for your home perusal), go to http://msdn2.microsoft.com/en-us/asp.net/bb944808.aspx, check the license agreement, and get them as a single downloaded compressed file.

Let’s now dig out some of these extensions to the JavaScript language and briefly explore the features of the built-in classes.

Important

The Microsoft AJAX JavaScript library is self-contained in the .js files you get from the aforementioned URL. This means that you can embed these files in any Web page and enjoy the object-oriented features of JavaScript regardless of whether or not ASP.NET AJAX is being used to power the page. For example, you can use the <script> tag to include all required JavaScript files in a PHP or classic ASP page and enjoy the advanced capabilities of the Microsoft AJAX JavaScript library.


JavaScript Language Extensions

The JavaScript language features a set of built-in objects, including Function, Object, Boolean, Array, Number, and String. All intrinsic objects have a read-only property named prototype. You use the prototype property to provide a base set of functionality shared by any new instance of an object of that class. New functionality can be added to the class prototype inside of an application to extend and improve the capabilities of a given class. This is exactly what the Microsoft AJAX library does.

Type information is the most important aspect of the JavaScript language that has been enhanced. Aside from instances of the base types, everything else in JavaScript is a plain object. With the library extensions, you have a type information system that is similar to the .NET Framework. The following code now works and displays “Person” instead of a generic “object” string:

var p = new Person("Dino", "Esposito");
alert(Object.getTypeName(p));

But where does the getTypeName method come from? It is a new method defined on the native JavaScript Object type. The Microsoft AJAX library contains code that defines new objects and extends existing JavaScript objects with additional functionality. Table 1 lists the main global objects defined in the library.

Table 1. Top-Level Objects in the Microsoft AJAX Library
PropertyDescription
ArrayExtends the native Array object. This object groups static methods to add, insert, remove, and clear elements of an array. It also includes static methods to enumerate elements and check whether a given element is contained in the array.
BooleanExtends the native Boolean object. This object defines a static parse method to infer a Boolean value from a string or any expression that evaluates to a Boolean value.
DateExtends the native Date object with a couple of instance methods: localeFormat and format. These methods format the date using the locale or invariant culture information.
ErrorDefines a static create method to wrap the JavaScript Error object and add a richer constructor to it. This object incorporates a couple of properties—message and name—to provide a description of the error that occurred and identify the error by name. A number of built-in error objects are used to simulate exceptions. In this case, the name property indicates the name of the exception caught.
FunctionExtends the native Function object. This object groups methods to define classes, namespaces, delegates, and a bunch of other object-oriented facilities.
NumberExtends the native Number object. This object defines a static parselocaleFormat and format. method to infer a numeric value from a string or any expression that evaluates to a numeric value. In addition, it supports a pair of static formatting methods:
ObjectExtends the native Object object. This object groups methods to read type information, such as the type of the object being used.
RegExpWraps the native RegExp object.
StringExtends the native String object. This object groups string manipulation methods, such as trim methods and endsWith and startsWith methods. In addition, it defines static localeFormat and format methods that are close relatives of the String.Format method of the managed String type.

After the Microsoft AJAX library has been added to the application, the following code will work just fine:

var s = "Dino";
alert(s.startsWith('D'));

The native JavaScript String object doesn’t feature either a startsWith or an endsWith method; the extended AJAX String object does.

One of the most common mistakes made when writing script code inside of Web pages is to use direct access to HTML elements instead of resorting to the getElementById method of the DOM. Suppose you have a text box element named TextBox1 in your client page. The following script code won’t work on all browsers:

alert(TextBox1.value);

The correct form ratified by the W3C paper for the HTML DOM standards is shown here:

alert(document.getElementById("TextBox1").value);

The correct form is clearly more verbose and bothersome to write over and over again. The Microsoft AJAX library comes to the rescue with the $get global function. Simply put, the $get function is a shortcut for the document.getElementById function. If the Microsoft AJAX library is in use, the following expression is fully equivalent to the one just shown:

alert($get("TextBox1").value);

The $get function has two overloads. If you call $get passing the sole ID, the function falls back into document.getElementById. Alternatively, you can specify a container as the second argument, as shown here:

var parent = $get("Div1");
$get("TextBox1", parent);

If the container element supports the getElementById method, the function returns the output of element.getElementById; otherwise, the $get function uses the DOM interface to explore the contents of the subtree rooted in the element to locate any node with the given ID.

Object-Oriented Extensions: Namespaces

In JavaScript, the Function object is the main tool you use to combine code with properties and forge new components. In the Microsoft AJAX library, the Function object is extended to incorporate type information, as well as namespaces, inheritance, interfaces, and enumerations.

A namespace provides a way of grouping and classifying types belonging to a library. A namespace is not a type itself, but it adds more information to the definition of each type it contains to better qualify the type. By default, all custom JavaScript functions belong to the global space of names. In the Microsoft AJAX library, you can associate a custom function with a particular namespace, for purely organizational reasons. When declaring a custom type in the Microsoft AJAX library, you can do as follows:

Type.registerNamespace("Core35");
Core35.Person = function Core35$Person(firstName, lastName)
{
this._firstName = firstName;
this._lastName = lastName;
}

// Define the body of members
function Core35$Person$ToString() {
return this._lastName + ", " + this._firstName;
}
...

// Define the prototype of the class
Core35.Person.prototype = {
ToString: Core35$Person$ToString,
get_FirstName: Core35$Person$get_FirstName,
set_FirstName: Core35$Person$set_FirstName,
get_LastName: Core35$Person$get_LastName,
set_LastName: Core35$Person$set_LastName
}

// Register the class, extending our own IntroAjax Person class
IntroAjax.Person.registerClass("Core35.Person");

The Type.registerNamespace method adds the specified namespace to the runtime environment. In a way, the registerNamespace method is equivalent to using the namespace {...} construct in C# or the Namespace .. End Namespace construct in Microsoft Visual Basic.

The Core35.Person function defined following the namespace declaration describes a Person type in the Core35 namespace. Finally, the newly defined function must be registered as a class with the Microsoft AJAX library framework. You use the registerClass method on the current function. The registerClass method is defined in the prototype of the Function object; as such, it is inherited by all functions. Internally, the registerClass method sets the _typeName property of the function to the first parameter of the method—the actual name of the class.

The registerClass method takes a number of parameters. The first parameter is mandatory, and it indicates the public name that will be used to expose the JavaScript function as a class. Additional and optional parameters are the parent class, if there is any, and any interface implemented by the class.

Note

In the definition of a new class, you can use an anonymous function or a named function. In terms of syntax, both solutions are acceptable. The convention, though, is that you opt for named functions and name each function after its fully qualified name, replacing the dot symbol (.) with a dollar symbol ($).


Object-Oriented Extensions: Inheritance

Let’s define a new class, Citizen, that extends Person by adding a couple of properties: an address and a national identification number. Here’s the skeleton of the code you need:

// Declare the class
Core35.Citizen = function Core35$Citizen(firstName, lastName, id)
{
...
}

// Define the prototype of the class
Core35.Citizen.prototype = {
...
}

// Register the class
Core35.Citizen.registerClass("Core35.Citizen", Core35.Person);

Note that the first argument of registerClass is a string, but the second one has to be an object reference. Let’s flesh out this code a bit.

In the constructor, you’ll set some private members and call the base constructor to initialize the members defined on the base class. The initializeBase method (defined on Function) retrieves and invokes the base constructor:

Core35.Citizen = function Core35$Citizen(firstName, lastName, id)
{
Core35.Citizen.initializeBase(this, [firstName, lastName]);
this._id = id;
this._address = "";
}

You pass initializeBase the reference to the current object as well as an array with any parameters that the constructor to call requires. You can use the [...] notation to define an array inline. If you omit the [...] notation, be ready to handle a parameter count exception.

Quite often, developers derive a class because they need to add new members or alter the behavior of an existing method or property. Object-oriented languages define a proper keyword to flag members as overridable. How is that possible in JavaScript? By simply adding a member to the class prototype, you mark it as overridable in derived classes. In addition, if the member already exists on the base class, it is silently overridden in the new one. Here’s the prototype of the Citizen class:

Core35.Citizen.prototype =
{
ToString: Core35$Citizen$ToString,
get_ID: Core35$Citizen$get_ID,
get_Address: Core35$Citizen$get_Address,
set_Address: Core35$Citizen$set_Address
}

The class has a read-only ID property and a read-write Address property. Furthermore, it overrides the ToString method defined in the parent class:

function Core35$Citizen$ToString()
{
var temp = Core35.Citizen.callBaseMethod(this, 'ToString');
temp += " [" + this._id + "]";
return temp;
}

You use callBaseMethod to invoke the same method on the parent class. Defined on the Function class, the callBaseMethod method takes up to three parameters: the instance, the name of the method, plus an optional array of arguments for the base method.

As mentioned earlier, the ToString method on the Person class returns a LastName, FirstName string. The ToString method on the Citizen class returns a string in the following format: LastName, FirstName [ID].

Object-Oriented Extensions: Interfaces

Finally, an interface describes a group of related behaviors that are typical of a variety of classes. In general, an interface can include methods, properties, and events; in JavaScript, it contains only methods.

Keeping in mind the constraints of the JavaScript language, to define an interface you create a regular class with a constructor and a prototype. The constructor and each prototyped method, though, will just throw a not-implemented exception. Here’s the code for the sample Sys.IDisposable built-in interface:

Type.registerNamespace("Sys");
Sys.IDisposable = function Sys$IDisposable()
{
throw Error.notImplemented();
}
function Sys$IDisposable$dispose()
{
throw Error.notImplemented();
}
Sys.IDisposable.prototype =
{
dispose: Sys$IDisposable$dispose
}
Sys.IDisposable.registerInterface('Sys.IDisposable');

The following statement registers the Citizen class, makes it derive from Person, and implements the IDisposable interface:

Core35.Citizen.registerClass('Core35.Citizen',
Core35.Person, Sys.IDisposable);

To implement a given interface, a JavaScript class simply provides all methods in the interface and lists the interface while registering the class:

function Core35$Citizen$dispose
{
this._id = "";
this._address = "";
}

Core35.Citizen.prototype =
{
dispose: Core35$Citizen$dispose
...
}

Note, though, that you won’t receive any runtime error if the class that declares to implement a given interface doesn’t really support all the methods.

If a class implements multiple interfaces, you simply list all required interfaces in the registerClass method as additional parameters. Here’s an example:

Sys.Component.registerClass('Sys.Component', null,
Sys.IDisposable,
Sys.INotifyPropertyChange,
Sys.INotifyDisposing);

As you can see, in this case you don’t have to group interfaces in an array.

The Application Core Component

The AJAX client library is made up of three main logical layers: JavaScript extensions, core framework classes, and user-interface (UI) framework classes. (See Figure 3.)

Figure 3. A graphical view of the Microsoft AJAX JavaScript library


As mentioned, JavaScript extensions add new methods and capabilities to native JavaScript objects and enable registration methods to simulate object-oriented constructs such as classes, namespaces, inheritance, and interfaces. The UI framework includes base components to define client behaviors, controls, DOM elements, and input devices such as keyboard and mouse buttons. The core framework classes form a sort of base library that incorporates a set of commonly used classes for event handling, string manipulation, Web services, debugging, and network operations.

The execution of each ASP.NET AJAX page is controlled by an application object that is instantiated in the body of the library. The application object is an instance of a private class—the Sys._Application class. Whenever an ASP.NET AJAX page is loaded in the browser, an instance of the Sys._Application class is promptly created and assigned to the Sys.Application object:

Sys.Application = new Sys._Application();

In addition, each ASP.NET AJAX page is injected with the following script code:

<script type="text/javascript">
<!--
Sys.Application.initialize();
// -->
</script>

This code is placed immediately after the closing tag of the page’s form, and it commands the loading of any script files registered for loading with the page’s script manager. As a result, the Sys.Application object is the nerve center of the ASP.NET AJAX page.

Note

JavaScript has no notion of private members; therefore, private members are conventionally indicated by the underscore symbol (_) prefixing their names.


The Sys.Application object serves one main purpose: providing access to page components. Its findComponent method scrolls the runtime hierarchy of Microsoft AJAX components for the current page until it finds a component with a matching ID. The method has two possible prototypes:

Sys._Application.findComponent(id);
Sys._Application.findComponent(id, parent);

The former overload takes the ID of the component, uses it to look up the component, and then navigates the hierarchy all the way down from the root. When a non-null parent argument is specified, the search is restricted to the subtree rooted in the context object. The id parameter must be a string; the parent parameter must be a Microsoft AJAX library object. The method returns the object that matches the ID, or it returns null if no such object is found.

The Microsoft AJAX library also supports a shortcut for retrieving runtime components—the $find method. The $find method is an alias for findComponent:

var $find = Sys.Application.findComponent;

You can use this method to locate all components created by server controls and extenders, as well as by your own JavaScript code. You can’t use $find to locate DOM elements; for DOM elements, you must resort to $get.

When a page using the Microsoft AJAX library page first loads up, the load event is fired for the client code to perform any required initialization. Note that the event refers to the page lifetime, not the application lifetime. So whenever a classic postback occurs, you receive a new load event. You don’t receive such events for any AJAX-style postback conducted via XMLHttpRequest. Likewise, the unload event is fired when the page is unloaded.

The load event occurs after a page has been loaded and initialized completely. For such a page, the load event is preferable to the browser’s onload for initialization purposes. Only when you get the Microsoft AJAX library load event, therefore, can you be sure that the page is ready for user interaction. The unload event occurs just before the Microsoft AJAX library runtime releases the page and all of its resources. For the sake of the application’s stability, you should use this event instead of the browser’s onunload event for clean-up tasks.

The easiest way to define load and unload handlers is by means of predefined function names: pageLoad and pageUnload. These functions need to be global and parameterless:

<script type="text/JavaScript" language="JavaScript">
function pageLoad()
{
alert("Being loaded");
}
function pageUnload()
{
alert("Being unloaded");
}
</script>

Because this piece doesn’t directly call into any of the Microsoft AJAX library objects—including Sys.Application—you can safely place it everywhere, even at the top of the page.

The Network Stack

AJAX libraries in general, and ASP.NET AJAX Extensions in particular, owe their growing popularity to their ability to execute out-of-band Web requests from the client. In particular, ASP.NET AJAX extensions allow you to invoke Web service methods as well as static methods defined on the code-behind page class. This ability leverages the networking support built into the Microsoft AJAX library.

In the Microsoft AJAX library, a remote request is represented by an instance of the Sys.Net.WebRequest class. Table 2 lists the properties of the class.

Table 2. Properties of the Sys.Net.WebRequest class
PropertyDescription
bodyGets and sets the body of the request
executorGets and sets the Microsoft AJAX library object that will take care of executing the request
headersGets the headers of the request
httpVerbGets and sets the HTTP verb for the request
timeoutGets and sets the timeout, if any, for the request
urlGets and sets the URL of the request

The WebRequest class defines the url property to get and set the target URL and the headers property to add header strings to the request. If the request is going to be a POST, you set the body of the request through the body property. A request executes through the method invoke. The completed event informs you about the completion of the request.

Each Web request is executed through an internal class—the Web request manager—that employs an “executor” to open the socket and send the packet. All executors derive from a common base class—the Sys.Net.WebRequestExecutor class.

The Microsoft AJAX library defines just one HTTP executor—the Sys.Net.XMLHttpExecutor class. As the name suggests, this executor uses the popular XMLHttpRequest object to execute the HTTP request.

Note

All AJAX libraries are associated with the XMLHttpRequest browser object. So what else could an executor be other than a reference to the XMLHttpRequest browser object? In general, an HTTP executor is any means you can use to carry out a Web request. An alternative executor might be based on HTTP frames. The idea is to use a dynamically created inline frame to download the response of a given request and then parse that result into usable objects.


DOM Events

Building cross-browser compatibility for events is not an easy task. Internet Explorer has its own eventing model, and so do Firefox and Safari. For this reason, the event model of the Microsoft AJAX library is a new abstract API that joins together the standard W3C API and the Internet Explorer nonextensible model. The new API is closely modeled after the standard W3C API.

In addition to using different method names (add/removeEventListener is for Firefox, and attach/detachEvent is for Internet Explorer), browsers differ in the way they pass event data down to handlers. In Internet Explorer, an event handler receives its data through the global window.event object; in Firefox, the event data is passed as an argument to the handler. In the Microsoft AJAX library, event handlers receive a parameter with proper event data.

Another significant difference is in the way mouse and keyboard events are represented. The Microsoft AJAX library abstracts away any differences between browsers by providing ad hoc enumerated types, such as Sys.UI.Key and Sys.UI.MouseButton. Here’s some sample code:

function button1_Click(e)
{
if (e.button === Sys.UI.MouseButton.leftButton)
{
...
}
}
function keyboard_EnterPressed(e)
{
if (e.keyCode === Sys.UI.Key.enter)
{
...
}
}

The Microsoft AJAX library provides a shorthand notation to create DOM event hookups and removal. For example, you can use the $addHandler and $removeHandler aliases to add and remove a handler. Here’s the syntax:

$addHandler(element, "eventName", handler);
$removeHandler(element, "eventName", handler);

In many cases, you’ll want to hook up several handlers to a DOM event for a component. Rather than manually creating all the required delegates and related handlers, you can use a condensed syntax to add and remove multiple handlers:

initialize: function()
{
var elem = this.get_element();
$addHandlers(
elem,
{[
'mouseover': this._mouseHoverHandler,
'mouseout': this._mouseOutHandler,
'focus', this._focusHandler,
'blur', this_blurHandler
]},
this);
}

The $clearHandlers alias, conversely, removes all handlers set for a particular DOM element in a single shot.

If you write a component and wire up some events, it is essential that you clear all handlers when the component is unloaded, or even earlier, if you don’t need the handler any longer. For example, you should do that from the component’s dispose method to break circular references between your JavaScript objects and the DOM. Correctly applied, this trick easily prevents nasty memory leaks.

Note

You won’t receive any event data if you bind the handler via markup—for example, by setting the onclick attribute of an <input> tag. Everything said here applies only to event handlers added via methods (and aliases) of the Sys.UI.DomEvent class. Events bound through attributes are still processed, but you have to resort to your knowledge of the browser’s event model to correctly grab associated information.


Other Facilities

The Microsoft AJAX library contains a number of other miscellaneous components to provide additional facilities to ASP.NET AJAX developers.

The Sys.StringBuilder class adds advanced text manipulation capabilities to ASP.NET AJAX pages. As the name suggests, the class mimics the behavior of the managed StringBuilder class defined in the .NET Framework. When you create an instance of the builder object, you specify initial text. The builder caches the text in an internal array by using an element for each added text or line. The Sys.StringBuilder object doesn’t accept objects other than non-null strings. The toString method composes the text by using the join method of the JavaScript array class.

The Microsoft AJAX library String class is also enriched with a format method that mimics the behavior of the Format method on the .NET Framework String class:

alert(String.format("Today is: {0}", new Date()));

You define placeholders in the format string using {n} elements. The real value for placeholders is determined by looking at the n.th argument in the format method call.

Another class that is worth mentioning is the Sys._Debug class. An instance of this internal class is assigned to the Sys.Debug global object:

Sys.Debug = new Sys._Debug();

In your pages, you use the Sys.Debug object to assert conditions, break into the debugger, or trace text. For example, the traceDump method writes the contents of the specified object in a human-readable format in the Microsoft AJAX library trace area. The trace area is expected to be a <textarea> element with an ID of traceConsole. You can place this element anywhere in the page:

<textarea id="traceConsole" cols="40" rows="10" />

The traceDump method accepts two parameters, as shown here:

Sys.Debug.traceDump(object, name)

The name parameter indicates descriptive text to display as the heading of the object dump. The text can contain HTML markup. Figure 4 shows the results.

Figure 4. The Microsoft AJAX library debugging tracer in action


Other  
 
Most View
Best Anti-Theft Apps For Your Smartphones
OS X Mountain Lion: What’s New - The System (Part 2)
Amazon Kindle Fire HD 8.9in - Is It Still Beautiful?
The Best Apps and Gear of 2012 (Part 9)
Ice Cream Sandwich Handsets – November 2012
What’s New In Speakers? – April 2013 (Part 2)
Lenovo IdeaPad Y480 Review – Laptop With Excellent Construction Quality And Ergonomic Design
Netbot - Essential Tweetbot for App.net
Lap Test – Asus Fonepad 7
Fujifilm X-E1 Digital Camera - A Concentrated X-Pro1
Top 10
Sharepoint 2013 : Farm Management - Disable a Timer Job,Start a Timer Job, Set the Schedule for a Timer Job
Sharepoint 2013 : Farm Management - Display Available Timer Jobs on the Farm, Get a Specific Timer Job, Enable a Timer Job
Sharepoint 2013 : Farm Management - Review Workflow Configuration Settings,Modify Workflow Configuration Settings
Sharepoint 2013 : Farm Management - Review SharePoint Designer Settings, Configure SharePoint Designer Settings
Sharepoint 2013 : Farm Management - Remove a Managed Path, Merge Log Files, End the Current Log File
SQL Server 2012 : Policy Based Management - Evaluating Policies
SQL Server 2012 : Defining Policies (part 3) - Creating Policies
SQL Server 2012 : Defining Policies (part 2) - Conditions
SQL Server 2012 : Defining Policies (part 1) - Management Facets
Microsoft Exchange Server 2010 : Configuring Anti-Spam and Message Filtering Options (part 4) - Preventing Internal Servers from Being Filtered