Introduction
In the first part of this series, we started with an example of a
simple web page that displays a Virtual Earth map on screen. The purpose of the code was to highlight some bad habits in writing markup and
JavaScript code. We promised ourselves to rewrite the same page in order to take advantage of ASP.NET and the new AJAX framework. This is
what we are going to do starting from part two of this series.
Ajax-enabled Server Controls
One of the strength of the ASP.NET programming model is the ability to encapsulate the markup of a portion of the page and render it
dynamically. The rendering logic is located inside an object called a Server Control. The responsibility of this object is simple: it
determines which HTML will be written to the response stream, based on decisions made at runtime. This means that the generated markup can
vary based on user preferences, environment configuration, and business logic. The dynamic generation of the HTML of a web page is the main
philosophy behind server technologies like ASP.NET.
As a consequence, our ASP.NET AJAX page will contain a Panel control, which is responsible for rendering the div element that
hosts the Virtual Earth map:
So far, everything is straightforward. In order to host a Virtual Earth map inside the div element, we need a Server Control
that performs two tasks:
- It renders a
script tag that loads the Virtual Earth API based on a default URL or one supplied by the
developer.
- It renders the JavaScript code needed to instantiate and load the map based on an initial configuration.
The code in listing 1 shows this Server Control declared in the ASP.NET AJAX page.
Listing 2: The VirtualEarthExtender control is an Ajax-enabled server control
The Server Control in the previous listing is not a typical ASP.NET control. In fact, it's a new kind of control - provided by
ASP.NET AJAX - called an Extender.
One reason for creating an Extender is that it lets you inject a script tag programmatically by instantiating an object of
type ScriptReference. However, this can be done with classic ASP.NET controls, simply by invoking one of the methods of the
ClientScriptManager object, which is accessible through the Page.ClientScript property. Actually, we are already gaining
something because we are encapsulating this logic inside a dedicated object, instead of interacting directly with the ClientScriptManager
class.
Where the Extender really shines is in its ability to instantiate and set up JavaScript objects. How can you do that with classic ASP.NET?
Well, you could build the JavaScript code as a big string and inject it in the page using the ClientScriptManager. No need to say, this isn't
a good approach. With ASP.NET, we can render markup dynamically, and yet we're relying on strings in order to inject JavaScript code in the
page.
With an Extender, we can solve this problem in the following way: we can associate a special JavaScript object, called a client Control,
to a HTML element in the page. In terms of ASP.NET markup, this means creating an Extender and associating it with another Server Control -
the "extended" control. Take a look at listing 1. Notice how we are associating the VirtualEarthExtender to the Panel through the
TargetControlID property.
At this point, the Extender is able to generate the JavaScript code needed to create an instance of the client Control and wire it to the
HTML rendered by the extended control (the Panel in our example). Furthermore, we can control - from the server side- how the JavaScript
object is initially configured.
Based on the previous discussion, this is what you are going to do in the following paragraphs:
- Create a client JavaScript Control that encapsulates the JavaScript code needed for creating and configuring a Virtual Earth
map.
- Create an Extender that instantiates and configures the JavaScript Control from the server side.
Client Controls
ASP.NET AJAX ships with a client library - written in JavaScript - called the Microsoft Ajax Library. With the help of this library, you
will create a client Control that encapsulates an instance of a Virtual Earth map.
Why create a wrapper over a VEMap object? There are multiple reasons. One is that the Microsoft Ajax Library enables you to do
component-based development on the client side. However, what interests us now is the possibility to use a client Control to manage the
lifecycle of our JavaScript object. Let's start by taking a look at the following listing, which reports the code for the
Mashup.VirtualEarth client Control.
Listing 3: Mashup.VirtualEarth Control
The first line tells the Microsoft Ajax Library to create a namespace called Mashup. Under this namespace, the
VirtualEarth control is declared as a function and then registered as a Control. This happens in the last line - the first after
the function body - through the call to the registerClass method. This method "upgrades" our JavaScript function to an ASP.NET
AJAX client class and makes it inherit from Sys.UI.Control, which is the base class for client Controls.
Note: The Microsoft Ajax Library lets you create namespaces and classes in JavaScript. We usually refer to these and other
constructs as "object-oriented patterns".
The base Sys.UI.Control class provides two interesting methods called initialize and dispose.
These are the best places to perform the initial setup and the final cleanup of an instance. An example is attaching event handlers in the
initialize method and then detaching the same handlers in the dispose method. As a consequence, this lets you
abandon the bad habit of hooking-up event handlers in the HTML. Furthermore, it enables you to detach handlers before the instance is
destroyed, thus avoiding potential memory leaks.
Managing the lifecycle of a JavaScript object is a good practice, and it's just one of the many features provided by client Controls.
Finally, look at how the Mashup.VirtualEarth function is declared. It accepts an argument called element and passes
the same argument to the base class by calling the initializeBase method. Every client Control is associated with one and only
one HTML element. In this example, the associated element will act as the container for the Virtual Earth map, since it's being passed to the
VEMap constructor inside the initialize method.
Now that you've got a client Control, you need to wire it to a server Control - an Extender. This will enable you to instantiate and
configure the client Control from the server side, without writing a single line of JavaScript code.
The VirtualEarth Extender
Now you are going to create a VirtualEarth Extender that lets you instantiate and configure an instance of the
Mashup.VirtualEarth client Control. To create an Extender, you have to declare a class that inherits from the base
ExtenderControl class, as shown in the following listing.
Listing 4: Declaring an Extender
Just before the class declaration, there's a TargetControlType attribute that specifies which server Controls can
be extended by our VirtualEarth Extender. In this case, you are restricting the extended Control to be a Panel, since it will render the div
element that will host the Virtual Earth map.
The next thing to do is declare some properties that allow setting the values of the counterpart properties of the client Control. The
following listing shows how it's done.
Listing 5: Mapping server properties to client properties
The InitialLatitude and InitialLongitude properties let you specify the coordinates of the initial
location at which the map is centered. When the Mashup.VirtualEarth instance is created on the client side, these values are
mapped to the initialLatitude and intialLongitude properties. The same thing happens for the ZoomLevel
property. The purpose of these server properties is to let the developer configure a JavaScript object - specifically, a client Control -
from the server side.
Finally, we need to write the code that creates an instance of the client Control and injects the references to the script files that
contain the JavaScript code. You accomplish this task by overriding two methods of the base ExtenderControl class:
GetScriptReferences and GetScriptControls. This is demonstrated in the following listing.
Listing 6: Working with Script Descriptors and Script References
The GetScriptReferences method returns a collection of ScriptReference objects. Each object specifies
the path to a JavaScript file. These paths (or URLs) will be injected in a script tag rendered in the page by the ScriptManager
control.
The RegisterScriptDescriptors method returns a collection of ScriptDescriptor objects. Script Descriptors are
used by the ScriptManager to render the JavaScript code necessary for creating and configuring an instance of a client component. In this
case, we are using a ScriptControlDescriptor because we are going to instantiate a client Control.
Behind the Scenes
Now that the Extender is ready, let's browse the ASP.NET page and take a look at the source code. The first thing to notice is that the
VirtualEarth Extender injected two script tags, just after those that reference the Microsoft Ajax Library files:
The first script tag references the Virtual Earth API, using the default URL or the one specified in the
ApiUrl property of the Extender. The second script tag references the Mashup.VirtualEarth client Control. Both
these scripts were referenced in the GetScriptReferences method of the Extender.
Finally, let's take a look at the JavaScript code injected in the page by the Virtual Earth Extender:
Sys.Application is a global object created by the Microsoft Ajax Library at runtime. This object accomplishes
some interesting tasks, such as hosting the client components instantiated on the client side. By calling the add_init method,
you can participate in the Init stage of the client side page lifecycle. There, you have the opportunity to instantiate and configure the
Mashup.VirtualEarth client Control. You can do that by calling the $create method and passing the configuration parameters, as
shown in the previous code snippet. Not only does $create offer a convenient syntax to instantiate client Controls; it also
allows Extenders to leverage the same syntax in order to automatically create instances of client components at runtime. As you can see,
everything has been setup on the server side, without actually writing a single line of JavaScript code.
In the next part of this series, we will expand our Virtual Earth Control and explore other kinds of interactions between the server side
and the client side of an ASP.NET AJAX Web Application.
Summary
In the second part of this introduction to ASP.NET AJAX, we introduced client Controls and Extenders. Thanks to the Microsoft Ajax
Library, we can do component-based development on the client side. We are able to encapsulate JavaScript code into a component that can be
initialized, set up and disposed in a standard way.
By creating an Extender, we can wire a client Control to a server Control. Then, we can configure the client Control on the server side
through the Extender's properties. Finally, Extenders take care of injecting in the page the necessary script references and the JavaScript
code that instantiates a client component.
About Alessandro Gallo
 |
Alessandro "Garbin" Gallo is a Microsoft MVP in the Visual ASP/ASP.NET category and a .NET developer/consultant. He is a contributor for the Ajax Control Toolkit project, owned by Microsoft. Alessandro won the Grand Prize at the "Mash-it-up with ASP.NET AJAX" contest held by Micr...
This author has published 23 articles on DotNetSlackers. View other articles or the complete profile here.
|
You might also be interested in the following related blog posts
ASP.NET MVC: DevExpress Mail Demo
read more
Export Word documents to XPS - Open XML Paper Specification format
read more
Bind InfoPath form to XML, Tables, SharePoint Lists & Web Services
read more
Create or Manage XPDL 1.0 & 2.1 packages using Aspose.Workflow
read more
Application Identifiers (AI) for EAN-128 barcode generation
read more
Announcing the WebsiteSpark Program
read more
Create charts & add ad hoc capabilities to .NET Web & WinForm apps
read more
Whats new in Aspose.Total for .NET Q1 2009?
read more
Telerik Introduces Free Web Testing Framework for ASP.NET AJAX and Silverlight
read more
CodeDigest.Com Article Digest - May,2009
read more
|
|
Please login to rate or to leave a comment.