Almost Too Easy! Creating Cross-Platform ASP.NET Applications Using Mono

he dream of cross-platform applications has been a holy grail of development since the dawn of the computer age. Most recently, the Java platform with its “Write once, run anywhere” is the promised end result of adopting the Sun philosophy. Java does deliver on those promises for the most part, but does so only at the cost of changing development platforms?a cost far too high for many developers steeped in the Microsoft way.

Microsoft’s Visual Studio makes it easy to develop Web-based applications using their ASP.NET environment. Until recently that meant you would have to host those applications on a system running Microsoft’s Internet Information Server (IIS). Now, however, thanks to the release of Mono 1.0 that restriction has been lifted.

Mono is an open-source cross-platform implementation of Microsoft’s .NET environment with support for the Common Language Runtime (CLR), a C# compiler, and ASP.NET using the XSP standalone server or an Apache add-in module (mod_mono). Mono currently runs on a large number of platforms including:

  • Microsoft Windows (2000 and above)
  • MacOS X (10.3?Panther only)
  • Sun Solaris
  • Red Hat 9.0/x86
  • Fedora Core 1/x86 and 2/x86
  • Slackware 10
  • SUSE Linux 9.0, 9.1, and Enterprise Server 8 for x86 Linux distributions

You can find instructions to get up and running with Mono on the downloads page of the Mono Web site.

The Test
To test the Mono cross-platform claims, I decided to build a simple family calendar application. The overall goal behind this project was to evaluate exactly how portable a reasonably complex application could be. Therefore, I developed the application in C# and ASP.NET on a Windows XP machine using Microsoft’s Visual Studio 2003, working from the following assumptions.

  • The project would best be written in C#. The current preferred language for developing to the Mono .NET implementation is C#. While you could use VB.NET you’re far more likely to run into a feature that hasn’t been implemented on Mono yet.
  • XML is a natural choice for storing the data for this application. Although Mono supports ADO.NET for accessing data in relational databases, it doesn’t support reading Microsoft Access (.mdb) files on any platform other than Windows. Using a full-featured relational database such as SQL Server, Oracle, MySQL, or PostgreSQL is overkill for this project. As Mono does provide full support for reading and writing data to XML files, that’s what I used for this demonstration. XML is a good format for storing and retrieving data in a cross-platform way but isn’t truly relational and probably wouldn’t work well for a large amount of data.
  • The same code would run on both Windows (IIS) and Mono (XSP). I tested the completed code using the standalone Mono ASP.NET server, XSP, on a machine running SUSE Linux 9.1, as well as on my development machine running Windows XP and IIS. XSP works great as a developmental server to test code and to run low-volume applications, but it’s definitely not suited for any high-hit-rate production Web server usage. For full-scale production usage you should target Apache using the mod_mono module (not tested).

Designing the Sample Application
The primary purpose of this application was to replace the whiteboard stuck to our kitchen refrigerator. While the whiteboard works well in terms of ease of use, it’s limited to showing a single month at a time and subject to data loss if someone happens to smudge the writing when retrieving an afternoon snack. It’s also time consuming to redraw a new calendar at the beginning of each month. Besides, I can’t check that calendar from work!

If cross-platform is one of your end goals in designing an application, you’ll want to watch for any code tied to a particular operating system. For example, platform-specific filenames and file paths will cause problems if you aren’t careful. Little things such as case sensitivity will bite you when you try to run the application on a different platform. Instead, use built-in features such as the Server.MapPath method to discover your application directory at runtime rather than hard coding paths to a specific location.

This simple example consists of a single Web form containing a calendar control and a data grid. One XML file holds an entire year’s worth of appointments. The application reads the XML file into a single DataSet when it first loads. It then displays the current month with appointment details displayed for the proper day (see Figure 1).

?
Figure 1. The Family Calendar Application: The application reads appointment data from an XML file into a DataSet and displays the current month by default with the appointments displayed in the appropriate day cells of the calendar.

Implementation
Writing the code was not that difficult. Even if you’re a novice at C# you’ll find lots of examples with a few simple Google queries. The Microsoft Visual Studio documentation and MSDN Web site are full of good information as well. I get a lot of good tips from reading Web logs. For example, the http://weblogs.asp.net site gathers feeds from various writers both inside and outside of Microsoft and aggregates them into a single feed.

One thing I really like about Visual Studio is the ability to create an ASP.NET page by just dragging and dropping controls onto the design surface. Once you have the controls on the page (a calendar control and a DataGrid in this case), you set the visual properties, add a few event handler stubs, and you’re ready to code.

For this application, the events.xml file holds the information for each event in a single record with the date, time, and description. Here’s what the file looks like with three events:

                   2004/8/5              Soccer Practice                 2004/8/10              Dr. Appt                 2004/8/10              Lunch w/ Carol        

To access a DataSet from any function within a page, you must instantiate it as a class-level variable. Place the code immediately after the calendar and DataGrid definitions inserted by the VS designer:

      protected DataSet dsEvents = new         DataSet("events");

Reading in the file requires one line of code:

   dsEvents.ReadXml (Server.MapPath ("events.xml"));

After loading the file, the DataSet contains a single table named event with three columns that hold the date, time, and description for each event. The application then loops through each item for the current month in the event database using the foreach keyword and renders each day individually using the DayRender function.

   private void Calendar1_DayRender(object sender,       System.Web.UI.WebControls.DayRenderEventArgs e)   {         DataGrid1.DataSource = dsEvents;         foreach (DataRow myDataRow in          dsEvents.Tables["event"].Rows)      {         string s = myDataRow["Date"].ToString();         if (s != "")         {            DateTime event_date = DateTime.Parse(s);            if ( (e.Day.Date == event_date) &&                (!e.Day.IsOtherMonth))            {               Label aLabel = new Label();               aLabel.Text = " 
" + myDataRow["Time"].ToString() + " " + myDataRow["Description"].ToString(); aLabel.Font.Size = FontUnit.XSmall; e.Cell.Controls.Add(aLabel); } } } }

Testing on Linux, Windows
A single "Run" button click in Visual Studio compiles the code, copies everything to the proper virtual directory, and loads the ASP.NET page into a browser. VS compiles the server-side C# code into a .dll file and places that in a directory named bin below the application root. Visual Studio provides full debugging support including the ability to set breakpoints, examine variables, and step through code.

Testing the application on the Linux side couldn't be easier. The simplest way to move the application over from Windows is to first copy the entire application virtual directory over to a shared drive. Then, from the Linux box, connect to the shared drive and copy the files to a working directory. On Linux, I created a directory named ASP in my Home directory and copied the files there. Then from a terminal window start up the XSP server with the command:

   mono /usr/bin/xsp.exe

That command launches the Mono Web server application, listening on the default port of 8080. To view the application you launch a browser and browse to the URL for your local server and the appropriate path and page, for example:

   http://localhost:8080/FamilyCalendar.aspx
?
Figure 2. The Family Calendar Application on Mono: As you can see, the application looks essentially identical when compiled and run with Mono.

The most amazing part of the entire process is the fact that you don't have to recompile anything. It just works! Well, almost works. While I wasn't able to get the app to work exactly as I wanted?the LinkButton for the day number doesn't appear in the current date cell of the calendar, so you can't click to make the event details display for the current day?everything else works (see Figure 2). That single difference is apparently a bug in the calendar control. I could still make the details DataGrid show up by using a JavaScript URL that causes a postback, sending the value that the LinkButton would normally send to the server (see the URL shown in Figure 2). After reporting the issue to the Mono developers list I was instructed to file a bug report. Hopefully this will be fixed in a future release. One temporary workaround would be to show the actual events only in the DataGrid and not in the calendar. Other than this minor and probably temporary glitch, the degree of compatibility is extremely high. I made no changes to the code to run it on both platforms.

Giant Steps
Building cross-platform ASP.NET applications has taken a giant step forward with the release of Mono version 1.0. While it's not (yet) one hundred percent compatible, it's certainly close. Future releases of Mono will add increased VB.NET support along with a host of other features. For more information on the direction of Mono, explore the Mono Website and check out the roadmap.

Mono makes it possible for companies or departments looking to implement a Web-based application using ASP.NET on non-Microsoft platforms. What's missing at the moment for full development on Linux is a good competitor to Microsoft's Visual Studio product. MonoDevelop is a port of the open source Windows-based SharpDevelop project. In its current release it does not have a graphical user interface designer, but the project developers plan to add one in the future. Until that happens though, if you have access to Visual Studio, you can use the VS designer to design your Web Forms, and then simply copy the code to your Mono project.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: