CoverStory
LANGUAGES: C#
ASP.NET VERSIONS: 2.0
Leverage the Web
Create Rich-client Web Interfaces with Atlas
By Dan Wahlin
As the Internet has evolved over the years, developers have experimented with different ways to provide end users with a rich browser experience that emulates features found in traditional desktop applications. One way of enhancing the end-user experience that has become more and more popular is the use of client callbacks. Client callbacks allow a browser to communicate directly with remote servers without performing multiple postbacks. This prevents unnecessary roundtrips between the browser and the Web server.
ASP.NET version 2 has built-in support for client callback features (sometimes referred to as out-of-band callbacks) that allows server controls to communicate directly from the browser to the server. Client callback features can also be found in many of today s popular Web sites, such as Google Maps (http://maps.google.com), MSN Virtual Earth (http://virtualearth.msn.com), and Microsoft Outlook Web Access.
In the past, developers relied on Internet Explorer 4 s XMLHTTP object or Microsoft s Remote Scripting technology (which relied on a specialized Java applet) to perform client callbacks. With Internet Explorer 5, Microsoft released a special JavaScript file called the WebService behavior that used the XMLHTTP object to send and receive XML data from remote Web services asynchronously. I wrote about the WebService behavior several years ago; for more information, see Create Efficient UIs. Even today, it s still a viable client callback option. However, it has one major flaw ... it only works in Internet Explorer 5 or later, which of course leaves out many others, such as Netscape, FireFox, Safari, and Opera.
Fortunately, most of today s modern browsers have built-in objects that emulate IE s XMLHTTP object. Although using these different browser objects is fairly straightforward, each browser requires slightly different JavaScript code which can be somewhat of a hassle. Even IE4 and IE5 require different code just to instantiate the XMLHTTP object. Other browsers that follow the Mozilla implementation use a completely different way of creating an object called XMLHttpRequest. Here s a simple example:
IE4: var request = new ActiveXObject( Microsoft.XMLHTTP );
IE5: var request = new ActiveXObject( Msxml2.XMLHTTP );
FireFox: var request = new XMLHttpRequest;
To mitigate some of these compatibility issues across browsers, several different technologies have arisen. One of the most popular is called AJAX (Asynchronous JavaScript and XML), which is a client-centric approach to providing cross-browser callbacks. AJAX is not a new technology and doesn t truly bring anything new to the table when compared to the XMLHTTP applications that people developed in the past. However, it has acted as a springboard for increasing awareness of client callback capabilities and how they can enhance Web applications. Several frameworks based on the AJAX concept have been released that allow developers to more easily communicate between a browser and a server. A .NET AJAX implementation can be found at http://sourceforge.net/projects/ajaxnet.
Microsoft s project code-named Atlas is an extension of the AJAX concept. It is based on XMLHTTP, as well as ASP.NET development principles making it relatively easy to use for developers of varying skill levels. Atlas provides many enhancements to JavaScript, such as object-oriented programming syntax, data types, namespaces, a type system, and more. It also provides several server controls and supporting JavaScript files that make client-side callbacks easy to implement.
Although Atlas is currently a technology preview, and will certainly be enhanced a great deal over the next few months, it is capable of performing a wide variety of tasks that will improve the end-user experience. In this article I ll demonstrate how to leverage Atlas to build a customer viewer utility that displays customer data, as well as maps showing the location of the customer s country. All of the functionality shown in the samples that follow will work cross-browser.
Installing Atlas
To use Atlas you ll need an assembly named Microsoft.Web.Atlas.dll, as well as several Atlas JavaScript support files. Get access to these files by downloading the Visual Studio.NET 2005 Atlas Blank Project VSI file located at http://beta.asp.net/default.aspx?tabindex=7&tabid=47 (note that this link may certainly change as new versions of Atlas are released). Installing the VSI file is as easy as opening it and clicking a few buttons to walk through the installation wizard. Once installed, you ll see a new Web site template displayed in VS.NET 2005, as shown in Figure 1.
Figure 1: Installing the Atlas Empty
Project VSI file adds a new template to the VS.NET project interface.
Once the ASP.NET Atlas Web Site template is selected, a new Web site will be created that has the Microsoft.Web.Atlas.dll file placed in the bin folder and has a folder named ScriptLibrary. The ScriptLibrary folder contains several JavaScript files that provide cross-browser callback support. The Atlas template also adds a default web.config file to the Web site that contains several configuration entries needed to run different Atlas features.
At the time this article was written, no Atlas-specific controls showed up in the VS.NET 2005 Toolbox after installing the VSI file. However, they can easily be added by right-clicking on the Toolbox and selecting Choose Items from the menu. Once the Choose Toolbox Items dialog box appears, browse to the Microsoft.Web.Atlas.dll assembly in the bin folder, select it, then click OK. Several different Atlas controls will show up in the Toolbox, as shown in Figure 2.
Figure 2: Although the initial
technology preview of Atlas doesn t automatically show Atlas controls in the Toolbox,
they can easily be added.
Providing Data to Atlas Controls
Now that you ve seen how to get the Atlas support files and create an Atlas Web project, let s take a look at exposing Northwind Customer data through a Web service that Atlas controls can consume using client-side callbacks. I started by creating a Customer object with four basic properties, as shown in Figure 3.
public class Customer {
private string _CustomerID;
private string _ContactName;
private string _CompanyName;
private string _Country;
public string Country {
get { return _Country; }
set { _Country = value; }
}
public string CompanyName {
get { return _CompanyName; }
set { _CompanyName = value; }
}
public string CustomerID {
get { return _CustomerID; }
set { _CustomerID = value; }
}
public string ContactName {
get { return _ContactName; }
set { _ContactName = value; }
}
}
Figure 3: The Customer object is a simple data container class that exposes properties.
After the Customer class was completed, a Web service named CustomersService.asmx was created. Two Web methods named GetCustomersByCountry and GetCustomersByID were then added to the Web service. The GetCustomersByCountry method is shown in Figure 4; notice that it returns an array of Customer objects. CustomersService.asmx has several other Web methods within it, such as GetCountries and GetCustomerIDs, which are used to support autocomplete functionality discussed later in the article (code examples referenced in this article are available for download; see end of article for details).
[WebMethod]
public Customer[] GetCustomersByCountry(string country) {
//SQL text used for simplicity...recommend using stored
//procedures though
string sql = "SELECT CustomerID,ContactName,CompanyName,Country " +
"FROM Customers";
if (!String.IsNullOrEmpty(country)) sql += " WHERE Country = '" +
country + "'";
DbConnection conn = GetDBConnection();
conn.Open();
DbCommand cmd = conn.CreateCommand();
cmd.CommandText = sql;
DbDataReader reader = cmd.ExecuteReader();
List
while (reader.Read()) {
Customer cust = new Customer();
cust.CustomerID = reader["CustomerID"].ToString();
cust.ContactName = reader["ContactName"].ToString();
cust.CompanyName = reader["CompanyName"].ToString();
cust.Country = reader["Country"].ToString();
custs.Add(cust);
}
reader.Close();
conn.Close();
return custs.ToArray();
}
private static DbConnection GetDBConnection() {
ConnectionStringSettings s =
ConfigurationManager.ConnectionStrings["ConnStr"];
DbProviderFactory f =
DbProviderFactories.GetFactory(s.ProviderName);
DbConnection conn = f.CreateConnection();
conn.ConnectionString = s.ConnectionString;
return conn;
}
Figure 4: The GetCustomersByCountry Web method exposes Customer objects that will be consumed by Atlas controls.
For calls to be made to the CustomersService.asmx Web service from the browser using Atlas controls, the service must be referenced in the page using a script tag. The following line of HTML code shows how this is done:
In addition to defining the path to the Web service in the src attribute, the path must also be followed by /js in order for it to be used successfully. The code needed to call the service will be discussed next.
Creating an Atlas Web Form
Now that the CustomersService.asmx Web service is ready, an ASP.NET Web Form can be created that can use Atlas controls to call the Web service and show data in the browser without doing any postbacks. Atlas provides two main options to make this possible.
The first option relies on client-side controls exposed via DHTML and JavaScript. Client-side controls allow Atlas to be used without requiring server-side controls, which will appeal to DHTML and JavaScript developers. Controls are defined by placing Atlas-specific XML tags into a script block with a type of text/xml-script, as shown in Figure 5.
Figure 5: XML syntax can be used to define Atlas client-side controls, as well as their behaviors and actions.
This code defines a textbox named txtCountry that will call the CustomersService.asmx file as a user types characters into the textbox. The autocomplete behavior for the textbox is defined using declarative XML syntax. This code also references several Atlas JavaScript files that support client-side callbacks. Although I m not going to cover the client-side controls within this article, you can read about them at the Atlas Quickstart Web site at http://atlas.asp.net/quickstart/default.aspx.
The second option for performing client-side callbacks is to use Atlas server controls. These controls look much like standard ASP.NET server controls, but are prefixed with atlas instead of asp . This option will appeal to ASP.NET developers who are accustomed to working with different types of server controls, especially because they can drag and drop the controls from the VS.NET 2005 Toolbox. Atlas ships with several default controls, as shown earlier in Figure 2.
To use the Atlas server controls you must first add a ScriptManager control to the page. This control handles loading all the necessary Atlas JavaScript support files into the page as it loads. An example of using the ScriptManager control is shown here:
Once the ScriptManager control is in place, other controls
that interact directly with the server (without performing post backs) can be
added. For this article s application, I added two
The data shown in the autocomplete list can be obtained by calling the CustomersService.asmx Web service mentioned earlier. This call to the Web service is possible without writing any JavaScript code. Instead, properties unique to the autocomplete feature can be applied to the Atlas TextBox control, as shown here:
AutoCompletionServiceUrl="CustomersService.asmx" AutoCompletionServiceMethod="GetCountries" AutoCompletionMinimumPrefixLength="1" /> The AutoCompletionServiceUrl property identifies the
CustomersService.asmx Web service; the AutoCompletionServiceMethod identifies
the GetCountries Web Method used to return data for the autocomplete list. The
AutoCompletionMinimumPrefixLength property controls when the autocomplete list
is shown to the end user. In this case, the autocomplete list is shown after
the user types one character into the textbox. An example of the autocomplete
feature in action is shown in Figure 6. Once a user enters a country name and clicks the submit
button, the customers associated with the selected country are obtained and
displayed in the page by calling the GetCustomerByCountry Web method in the
CustomersService.asmx Web service. The button s onClick attribute is wired to a
JavaScript function named GetCustomerByCountry, which makes the Web service
call. The call is made asynchronously, which means the end user can continue to
interact with the browser as the country data is being retrieved. Once the data returns from the Web service, a client-side
callback function named OnWSRequestComplete is called, which handles binding
the returned data to an Atlas ListView control. Figure 7 shows the JavaScript
code needed to call the Web service and bind the data (again, without any
postback operations). Notice that the Web service is called using its namespace
(XmlForAsp.Atlas), class name (CustomersService), and method
(GetCustomersByCountry). function GetCustomerByCountry() { var country =
document.getElementById("txtCountry").value; //Call Web Service XmlForAsp.Atlas.CustomersService.GetCustomersByCountry(country, OnWSRequestComplete); } function OnWSRequestComplete(result) { //searchResults is an
Atlas ListView control var searchResults =
document.getElementById("searchResults"); //Bind returned data to
ListView control searchResults.control.set_data(result); if (result != null)
GetMap(result[0].Country); } Figure 7: Atlas
provides an object-oriented enhancement to JavaScript that allows Web services
to be called using syntax similar to C# code. This example calls the
GetCustomersByCountry Web method. Upon returning data, the OnWSRequestComplete
function is called, which handles binding the data. Although I chose to use JavaScript to call the Web service,
I also could have performed the action by using an The Atlas ListView control (named searchResults in Figure
7) acts much like the ItemTemplateControlID="row" CssClass="listView" ItemCssClass="item" AlternatingItemCssClass="alternatingItem"> Property="text" /> Figure 8: Using
the Atlas ListView control s LayoutTemplate template. Microsoft s MSN Web site has recently added a new service
called Virtual Earth that provides advanced mapping and viewing capabilities (http://virtualearth.msn.com).
Virtual Earth makes it easy to view pictures of buildings or land areas with
just a few clicks of the mouse. It also exposes advanced client-side
functionality that allows end users to move a map around without posting back
to the server. To make it easy to add Virtual Earth capabilities to Web
Forms, Atlas ships with a VirtualEarthMap control. This control displays map
locations based on longitude and latitude, and allows pushpins to be added
(markers on the map that identify certain landmarks). To make the customer
viewer application discussed in the article a little more interesting, I added
Virtual Earth mapping to the page to display customer countries. This was done
by adding the following code to the Web Form: ZoomLevel="4" Latitude="35.7"
Longitude="-105.59" MapStyle="hybrid"> As a customer (or group of customers) is selected based on
country, the VirtualEarthMap control is dynamically assigned the longitude and
latitude of the country. This causes the map to automatically move to the
selected country and display it, as shown in Figure 9. The longitude and
latitude of the selected country is obtained by calling a Web method named
GetCountryLongLat in the CustomersService.asmx Web service discussed earlier
using JavaScript (the complete code for this call is available with this
article s downloadable code). The ability for Web pages to dynamically make client-side
callbacks to remote servers using Atlas provides an excellent way to enhance
user interfaces and make them more responsive. Technologies such as the WebService
behavior allow this type of functionality to occur quite easily, but don t
provide cross-browser support. With the release of various AJAX
frameworks and the new Microsoft Atlas framework, cross-browser client-side
interactions have been greatly simplified and been made more accessible to a
wide range of developers. Although the Atlas code and controls mentioned in this
article will most certainly change as the framework matures and reaches Beta
status, you can see that making calls from a Web page to a back-end server can
be done fairly easily using Atlas controls. Atlas functionality won t be needed
in every Web application. However, there are many applications that can benefit
from it. To see a live video of this article s sample Atlas application in
action visit http://www.xmlforasp.net/videos/Atlas/CustomerViewer.wmv. The sample code in
this article is available for download. Dan Wahlin
(Microsoft MVP for ASP.NET and XML Web services) is the president of Wahlin
Consulting and founded the XML for ASP.NET Developers Web site (http://www.XMLforASP.NET), which focuses
on using XML, ADO.NET, and Web services in Microsoft s .NET platform. He s also
a corporate trainer and speaker, and teaches XML and .NET training courses
around the US. Dan
coauthored Professional Windows DNA
(Wrox), ASP.NET: Tips, Tutorials and Code
(SAMS), and ASP.NET 1.1 Insider Solutions
and authored XML for ASP.NET Developers
(SAMS).
Figure 6: The autocomplete feature
displays dynamic data to end users as they type into a textbox. Although a
drop-down list containing countries could have certainly been used in this
situation, the autocomplete feature allows people to type data or select it
based on their personal preferences.
Adding Virtual Earth Mapping Capabilities
Figure 9: The VirtualEarthMap
control makes it easy to display maps within a Web Form with only a minimal
amount of code. Conclusion