Channels ▼
RSS

Web Development

ASP.NET & Multiplatform Environments

Source Code Accompanies This Article. Download It Now.


Marcia is chief technology officer at Gulesian Associates and author of more than 100 articles on software development. She can be contacted at marcia.gulesian@ verizon.net.


Running .NET web applications in the enterprise means accommodating a myriad of servers and browsers, many with distinct behaviors (see Figure 1). The traditional approach to building complex web apps for such environments is to write separate versions of your code—each meant to run correctly with an individual server and browser pair. In this article, I examine some of the challenges you face when creating a single version of .NET web apps, so that they function the same way no matter which server it's deployed to, and whichever client it's downloaded to.

Thin clients, in which data is managed and stored centrally, are being adopted for a number of reasons. For one thing, federal regulations (Sarbanes-Oxley, the Homeland Security Act, and HIPPA, among others) dictate that internal documents and communications be secured to a heretofore-unseen level, and security is easier to achieve when data is managed and stored centrally. Second, there's the high total-cost-of-ownership of the PC desktop. Additionally, networks have gotten faster, with most businesses running 100-Mpbs Fast Ethernet or 54-Mbps 802.11g Wi-Fi networks (both more than fast enough for thin-client computing). Finally, many vendors are shipping thin clients—with or without embedded Windows XP but all with web browsers—with enough resources locally that you don't waste time waiting for your system to painfully render its GUI.

At the same time, Linux is being supported by vendors such as IBM and Oracle, and .NET apps, which can run on Linux (and other flavors of UNIX), are not dependent solely on the Windows IIS application server and your web browsers—a one-to-many relationship. Enterprise-based .NET apps are now running in many-to-many server-browser pair environments, as in Figure 1. Finally, Linux is appearing on mainframes and other powerful computers that manage and store data centrally for large numbers of users.

On the server side, the standardization of C# and .NET's Common Language Runtime (CLR) lets you use open-source tools that are based on a language that is an international standard and compatible with both Microsoft and various UNIXs. This has given rise to initiatives such as Mono, an open-source development platform based on the .NET Framework that lets you build cross-platform applications (http://www.mono-project.com/). Mono's .NET implementation is based on the ECMA standards for C# and the Common Language Infrastructure (CLI). While Mono includes both developer tools and the infrastructure needed to run .NET client and server applications, I focus here on ASP.NET apps developed with Microsoft's Visual Studio .NET and deployed to both Microsoft's IIS (Windows) and the Apache Software Foundation's Apache HTTP server (after the addition of the Mono module).

On the client side, .NET apps downloaded to different browsers (running on a "thin" or "thick" client) exhibit different behaviors as a function of both the browser and the server from which it was downloaded. I first review how adjustments in the .NET configuration files can compensate for the problematic behavior of certain browsers when they download an app from the IIS application server (Windows). Then, I show how Mono can be used to mask the behaviors of these same browsers when downloading the same app from an Apache (Mono) server.

As Figure 1 suggests, the plethora of server-browser combinations is too large for a single article. However, I present a number of representative cases that can be used as building blocks to creating a single version of a .NET web app that functions the same way whichever server it is deployed to and whichever client downloads it.

Uplevel and Downlevel Browsers

Browsers are split into two distinct groups: uplevel and downlevel browsers. These groups define the type of native support a browser offers, and generally determine the rendering and behavior of a page downloaded from a web server.

Browsers that are considered uplevel at minimum support ECMAScript (JScript, JavaScript) 1.2; HTML 4.0; Microsoft Document Object Model (MSDOM); and Cascading style sheets (CSS).

On the other hand, downlevel browsers only support HTML 3.2 (http://aspnet.4guysfromrolla.com/demos/printPage.aspx?path=/articles/051204-1.aspx).

In practice, only modern Microsoft Internet Explorer versions fall into the uplevel category; most other browsers fall into the downlevel category.

Server controls such as dropdown lists and text boxes can behave differently for each browser type. If users have uplevel browsers, the server controls generate client-side JavaScript that manipulates the MSDOM and traps the action events directly on the client. If users have downlevel browsers, the controls generate standard HTML, requiring that browsers perform round-trips to the server for triggered action events.

Because different web browsers—and different versions of the same browser—have different capabilities and behaviors, web developers usually have to change their applications based on which user's browser their code detects. They use two general approaches to this problem:

  • Code (typically JavaScript) is sent along with the page to be executed client-side.
  • The user-agent string from the HTTP requests headers is analyzed server-side and only the appropriate HTML code is sent to the client.

Often a combination of the two is employed (see http://msdn.microsoft.com/asp.net/using/migrating/phpmig/whitepapers/ compatibility.aspx?print=true and http://msdn.microsoft.com/library/default.asp?url=/ library/en-us/vbcon/html/vbconwebformscontrolsbrowsercapabilities.asp).

In addition, given the existence of Rhino (Mozilla.org's JavaScript implementation in Java) and IKVM.NET (a JVM implementation for the CLR), it should be possible to run JavaScript directly under Mono (see http://chimpen.com/things/archives/001427.php).

ASP.NET's Adaptive Rendering

Figure 2 shows a web app downloaded from a Microsoft IIS application server by an Internet Explorer 5.5 or later browser running on a PC. The rendering is the same as the original design of the app in a Visual Studio .NET IDE. However, .NET controls such as single- and multiline text boxes or labels appear distorted on the page when deployed to an IIS application server and downloaded by a downlevel browser such as Safari or Konqueror; see Figures 3(b) and 4(b). That's because the HTML rendered by .NET web controls depends on the browser requesting the ASP.NET web page. And, Safari and Konqueror browsers render HTML 3.2-compliant HTML by default, in this situation. However, adding Listings One and Two to your web.config (or machine.config) file causes these browsers to render the .NET web controls of your app (or all apps running on the server) using HTML 4.0-compliant markup.

When Listings One and Two are added to the <browserCaps> section of the Machine.config file on the IIS server where .NET web apps are running, the web controls in all apps running on that host render without distortion in Safari (Mac), Konqueror (Linux), and Internet Explorer (PC) browsers; see Figures 2, 3(a), and 4(a). What is most interesting is that the undistorted rendering in Figures 3(a) and 4(a) is also seen in all browsers when the same application is copied to and downloaded from the Mono server without the use of Listings One and Two! To help account for changes in the browser marketplace, cyScape (http://cyscape.com/browsercaps/) publishes regular updates for the browsercaps section of your machine.config file. It is important that you keep this data current. Otherwise, pages that depend on browser detection may not operate as expected due to changes in the browser marketplace.

ASP.NET Validation

The default ASP.NET 1.1 validation controls do not provide a working client-side script model for nonMicrosoft browsers, due to the fact that the proprietary script document.all[ID] is used in place of the standards-compliant script document.getElementById(ID) for referencing an element in the HTML document. If you look at the View Source in a downlevel browser and compare the code with the View Source of the IE browser, the client-side code for the validation controls is absent in the downlevel browser's View Source. Client-side support can be added, but at the cost of recreating the validation controls. Fortunately, the work has already been provided by Paul Glavich (http://weblogs.asp.net/pglavich/), so you can use his DomValidators validation controls if you need to support client-side validation with nonMicrosoft browsers.

Other solutions are provided by third-party tools such as Peter Blum's Validation Controls (http://www.peterblum.com/), which emit client-side validation code in Safari browsers. Blum's solution requires some work to install and configure before Visual Studio .NET 2003 can take advantage of these components, but they do work well. Another solution (my preference) is to hand-code custom server-side validation, or you can settle for client-side validation in IE and server-side validation in all other browsers. Or you can wait until ASP.NET 2.0 ships.

It's worth noting that this technique does have JavaScript issues. For instance, Listing Three works in IE, Safari, and Konqueror browsers, Listing Four works only in IE browsers, and Listing Five works in IE (PC) but not Safari (Mac OS X) or Konqueror. (Listing Five exploits a security bug in some browsers, IE for instance, that lets you close the current window even if it wasn't opened with client-side scripting.

Conclusion

With Mono and most all Linux distributions bundling Java support, it's important to include Java in any discussion that considers thin clients. In mid 2004, IBM began offering a Java-based thin software application, called "Workplace," intended for web-based applications. And, the comparative examples of JavaScript code presented here apply equally well to servlet- and JSP-based Java apps.

However, it's also important not to compare apples with oranges. At the end of 2004, you were likely to have been developing with .NET 1.1 and/or Mono 1.0 and/or JDK 1.4. In the coming months, however, you can add .NET 2.0, Mono 1.2, and JDK 1.5 to the mix.

Of course, C# and Java are playing leapfrog. C# started out with many of Java's features and some useful improvements of its own, and now Java is taking a number of C# features—attributes, enums, foreach, and autoboxing—and adding generics, static imports, and extendable enums. With the release of ASP.NET 2.0, Microsoft will reduce the amount of coding required for a normal web site drastically, in some cases more than 50 percent. Microsoft has also added to all the out-of-the box User controls and Validation controls, and created a new concept of Master pages, which should reduce the size of your web site. With J2EE 5.0 (previously J2EE 1.5), the Java community is likewise making it easier for less-experienced developers to create applications.

The bottom line, as suggested by Figure 1, is that .NET apps have now followed J2EE apps into the world of multiplatform deployment, which calls for a new and expanding skill set on the part of .NET developers. While both the Mono and .NET Frameworks need to be considered during the planning stage of your next ".NET" web application, this consideration needs to include your ability to work with operating systems and browsers other than just Windows Server and Internet Explorer, respectively. Failure to do so can put you at a competitive disadvantage.

References

Mark Easton and Jason King, Cross-Platform .NET Development. Apress, 2004.

Brian Nantz, Open Source .NET Development. Addison-Wesley, 2005

DDJ



Listing One

<!-- AppleWebKit Based Browsers (Safari...) //-->
  <case match="AppleWebKit/(?'version'(?'major'\d)
                                          (?'minor'\d+)(?'letters'\w*))">
    browser=AppleWebKit
    version=${version}
    majorversion=${major}
    minorversion=0.${minor}
    frames=true
    tables=true
    cookies=true
    javascript=true
    javaapplets=true
    ecmascriptversion=1.5
    w3cdomversion=1.0
    css1=true
    css2=true
    xml=true
    tagwriter=System.Web.UI.HtmlTextWriter
    <case match="AppleWebKit/(?'version'(?'major'\d)
                                        (?'minor'\d+)(?'letters'\w*))
                                        (\(KHTML, like Gecko\) )?
                                        (?'type'[^/\d]*)/.*$">
    type=${type}
    </case>
  </case>
Back to article


Listing Two
<!-- Konqueror //-->
<case match = "Konqueror/(?'version'(?'major'\d+)
                         (?'minor'\.\d+)(?'letters'));\w*(?'platform'[^\)]*)">
browser=Konqueror
version=${version}
majorversion=${major}
minorversion=${minor}
platform=${platform}
type=Konqueror
frames=true
tables=true
cookies=true
javascript=true
javaapplets=true
ecmascriptversion=1.5
w3cdomversion=1.0
css1=true
css2=true
xml=true
tagwriter=System.Web.UI.HtmlTextWriter
</case>
Back to article


Listing Three
function disableTextBox() { 
var selectElement = document.getElementById('ddlWhatever');
var len = selectElement.options.length;
for (var i= 0; i < len; i++){
var bln = selectElement.options[i].selected;
var val = selectElement.options[i].value;
if (bln == true){
if (val == 'ABC'){
document.Form1.TextBox1.disabled = true; 
                //  Works in I.E. (PC), Safari 1.0.2 & 1.2.2, and Konqueror
//document.Form1.TextBox1.readOnly = true;
                //  Works in I.E. (PC), Safari 1.2.2, and Konqueror
//document.getElementById("TextBox1").setAttribute("readOnly",true); 
//  Works only in I.E. (PC)
}
else{
document.Form1.TextBox1.disabled = true; 
            //  Works in I.E. (PC), Safari 1.0.2 & 1.2.2, and Konqueror
//document.Form1.TextBox1.readOnly = true; 
            //  Works in I.E. (PC), Safari 1.2.2, and Konqueror 
//document.getElementById("TextBox1").setAttribute("readOnly",true); 
            //  Works only in I.E. (PC)
}
} 
} 
}
Back to article


Listing Four
function launchWindow() {       
if (document.getElementById("ddlWhatever").getAttribute("value") == 'ABC')
{
var dateWin;
dateWin = window.open("Page1.aspx",'');
dateWin.focus();
}
else
{
var dateWin;
dateWin = window.open("Page2.aspx",'');
dateWin.focus();
}
}
Back to article


Listing Five
window.opener=self;
window.close();
Back to article


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 
Dr. Dobb's TV