The LAMA Stack

Run Dynamic Web Sites or Servers Using Linux-Apache-MySQL-ASP.NET





The LAMA Stack

Run Dynamic Web Sites or Servers Using Linux-Apache-MySQL-ASP.NET


By Oscar Peli


The Mono Project released a new version (2.0) of Mono last fall. Mono is an open source project that implements a .NET Framework porting on platforms like Linux, Solaris, and MacOS. With this version, the project offers many opportunities to .NET developers. For example, it is now possible to develop an ASP.NET 2.0+ application on your preferred IDE and run it on Linux or MacOS, simply with a copy of files (assemblies included).


In this article we ll develop a data-driven application based on a MySQL database. You ll analyze a MySQL provider and understand how to deploy an application to an openSUSE server. At the end of the article we ll look through some advanced features regarding LINQ (language-integrated query) that also is supported by Mono.


The LAMP Stack

If you are a Microsoft-based developer, accustomed to working with Windows, Internet Information Server, and SQL Server, you may not be familiar with the LAMP stack. A quick search on Wikipedia will show that the acronym LAMP refers to a solution stack of software, usually free and open source software, used to run dynamic Web sites or servers. The original expansion is as follows:


Linux-Apache-MySQL-PHP (or Perl or Python). The goal of this article is to build a new version of the stack where the language ( P ) is substituted by ASP.NET (Mono). So we are going to build the new LAMA stack: Linux-Apache-MySQL-ASP.NET.


To get started, you must understand how to manage all the components of the stack that (probably) are new for you (at least the first three).



Space constraints and the scope of this article limit me from being able to provide a thorough discussion about Linux and Apache. For this article we ll provide the bare essentials for you to run your application under the new LAMA stack. If you already own a Linux-based server, you can download the latest Mono version from (Version 2.0.1 was available at the time of this writing, but it is possible that by the time you read this a newer version will be available.) Browsing the link, you ll find versions of Mono for several supported Linux flavors: openSUSE, RedHat, and Solaris; but if you are absolutely new to Linux, you have the better choice in an openSUSE VMware image that contains the latest Mono version pre-installed and pre-configured, and all the other components (Apache, MySQL) you ll need for your application to run. To execute the VMware image, download the free VMware player from You also can use this image with any VMware product compatible with VMware Workstation. Read carefully the instructions for using the VMware image (


Once you ve downloaded and unzipped the image and the player, you can run your first Linux machine by simply double-clicking the mono.vmx file. The image is pre-configured, so you ll log in as the linux user (with the password mono ).


The next step you must perform is the configuration of the Apache Web server. As with Internet Information Server, you also must configure the virtual directory of your application on the Apache Web server. To do so, add some lines to the httpd.conf file that you ll find under the /etc/apache2 directory. You need administrator rights to modify this system file, so you must log in as the root user (with the password mono ). Once logged-in as root , open a File Browser and go to the /etc/apache2 folder; find the httpd.conf file and edit it with the pre-installed gedit editor (right-click on the file and select Open with gedit ); finally, add these lines:


AddMonoApplications default "/lama:/srv/www/htdocs/LAMA"

   SetHandler mono


In this way, you define your virtual directory lama that points to the /srv/www/htdocs/LAMA folder. You also tell Apache that all the files inside this virtual directory will be handled by Mono. Save the file and restart Apache running the following command inside a shell (to open a shell click on Gnome Terminal from the Computer main menu):


/etc/init.d/apache2 graceful


Now you can find a nice database with which to work.



Already installed and pre-configured in your VMware image is a MySQL database (version 5.0.51a). To run a data-driven application, we can use the world sample database that you can download starting from the MySQL documentation page ( Once you ve extracted the world.sql file, you must load it into MySQL; open a command shell (use the root Linux user), then change to the directory where you stored the world.sql file. From this location type:


mysql -u root -p


This command starts the MySQL monitor, a command line tool to interact with MySQL. You connect MySQL as the root user, with all the rights to manage the server. When prompted for the root password, simply leave it blank and press Enter (remember that the MySQL root user is different from the openSUSE root user). You ll see something similar to Figure 1 if you ve done that all correctly.


Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 13

Server version: 5.0.51a SUSE MySQL RPM

Type 'help;' or '\h' for help. Type '\c' to clear

the buffer.


Figure 1: The MySQL monitor.


Type help if you need to know which commands are available from the MySQL monitor. To create the world database and to use it as a default database, type the following commands:


mysql> CREATE DATABASE world;

Query OK, 1 row affected (0.00 sec)

mysql> USE world;

Database changed


Finally, to load data into the new database, type:


mysql> SOURCE world.sql;


You ll see some output; at the end, type exit to return to the command shell.


As usual in Linux, you can manage servers via command line tools. Of course, using a GUI tool is more suitable; present in your VMware image is a PHP application that lets you manage MySQL via a Web interface; from your host machine, simply type the following address inside Linux: http://localhost/phpMyAdmin or http://yourLinuxaddr/phpMyAdmin. Figure 2 shows the application started from the host while the Linux server took the address.


Figure 2: A GUI tool to administer MySQL.


You can use phpMyAdmin to check which kind of data you loaded from the world.sql file, and you can create a new user we ll use to access the world database. Simply use the Privileges link to add the user lama with password lama . You can start to develop your data-driven application once you ve set up your data environment.



First we must look for a suitable provider for MySQL. Starting from the MySQL page on the Mono project site (, you can find an advised provider to download: MySQL Connector/Net ( The downloaded zip file contains a Windows msi file that installs a lot of stuff, like documentation, samples, etc. (see Figure 3).


Figure 3: MySQL Connector Net installation.


We can build the sample application once the MySQL provider is installed (you ll know what the installation did as you continue through the article).


You ll find a Visual Studio 2008 solution in the accompanying support files (see the LAMA folder) that already contains all the stuff we are going to develop (see end of article for download details). First you must know that the last version of the Microsoft IDE was chosen because you ll see how to use LINQ against MySQL. You can use Visual Studio 2005 if you want to develop an application that doesn t use those features supported only by the last version of the .NET Framework.


You may use a MasterPage approach to make your solution more professional; in this case, find in LAMA.master a simple example where you put a common header for your pages.


The first example to analyze, First.aspx, contains a GridView control used to query the world database tables. In the page s declarative part, you can use a System Messages label and the GridView control (see Figure 4).


 ContentPlaceHolderID="cphContent" Runat="Server">

System Messages:

 runat="server" />

 PageSize="50" AllowPaging="true"


 ShowFooter="true" ShowHeader="true"







 HorizontalAlign="Right" BackColor="#C6C3C6"/>

Figure 4: A GridView to query the MySQL database.


To check all the features supported inside Linux, you can enable paging and sorting to manage the relative events.


Looking at the code-beside in Figure 5 (First.aspx.cs), you call the GetAllRows private method in the Page_Load event to load data into a private DataSet object.


protected void Page_Load(object sender, EventArgs e)


 gvDataSet = GetAllRows("City");

 if (!Page.IsPostBack)


 // Databind



  gv.DataSource = gvDataSet.Tables[0].DefaultView;



 catch (Exception ex)


  lblSysMess.Text += ex.Message;




Figure 5: The Page_Load event from First.aspx.cs.


The relevant portion of the code is contained inside the GetAllRows method (see Figure 6). Here you can find all the MySQL provider methods that let you query the database.


private DataSet GetAllRows(string inTable)


 string connString = System.Configuration.


 DataSet ds = new DataSet();



 // Build the connection to the database

 MySqlConnection dbcon = new MySqlConnection(connString);


 string sql = "SELECT * FROM " + inTable + ";";

 // Create the select command

 MySqlCommand dbcmd = new MySqlCommand(sql, dbcon);

 System.Data.Common.DataAdapter da;

 // Create the DataAdapter to load data

 da = new MySqlDataAdapter(dbcmd);

 // Fill the DataSet



 dbcmd = null;


 dbcon = null;


 //catch { }

 catch (Exception ex)


 lblSysMess.Text += ex.Message;


 return ds;


Figure 6: Using the MySQL provider.


As you can see, you can find methods similar to those you use against SQL Server. So, you ll use a MySqlConnection object to establish a connection to MySQL, a MySqlCommand to build a command to run against MySQL, and a MySqlDataAdapter to load data.


To use those objects you must add a reference to the MySQL provider. The MySQL installation package deals with the Global Assembly Cache installation of the MySql.Data assembly, so you can find the provider in the .NET components (see Figure 7).


Figure 7: MySql.Data is present in the GAC.


Of course, when you deploy your application to Linux, you ll either install the assembly in the Linux GAC, or copy the assembly inside the bin directory of your application (the latter option was chosen in the accompanying support files).


Note: You can start to build a multiplatform application if you encapsulate the GetAllRows method inside a Data Access component. Of course, multiplatform now not only refers to database systems, but even to those operating systems supported by Mono.


Deploy Your Application to Linux

Now that we ve set up a data environment and developed a data-driven application, we can deploy it to Linux. As you know, the deploying process is simply to copy your application files (assemblies included) to the destination folder. Open your File Explorer application and type the IP address of your Linux machine to copy files between your host machine and the Linux image (see Figure 8).


Figure 8: A Linux share.


Open a command shell and type the following command to find the current IP address of your Linux machine:




Once you ve typed the correct address, File Explorer will ask you for the credentials to access the folders. Use the linux user (with password mono ). Now you can drop the application folder on to the htdocs directory (the Apache home directory). If you ve done all the steps correctly, you can open your preferred browser on your host machine and try the application (see Figure 9).


Figure 9: Your first ASP.NET application running under Linux.


Well done! Your first ASP.NET application runs under Linux. Try to paginate or sort the grid to test the functionalities of your application.


Note: Every time you copy to Linux a newer version of your application, you must restart Apache with the following shell command:


/etc/init.d/apache2 graceful


Of course, you must have permissions to execute this command, so if you re logged in as the linux user, you must type this command inside the command shell:


su root


Press Enter, then type the root password (mono). In this way you re the root user inside the command shell and you have permission to restart Apache.


Using LINQ on Linux

One of the best new features of Mono 2.0 is the wide LINQ support. From the release notes page ( you can read: LINQ and LINQ to XML are now complete, support for expression trees is now available as well as the backend to support expression tree compilation. LINQ to Dataset has also been implemented . There is not enough space here to offer complete details of the LINQ features; if you want to explore all the LINQ to X technologies, start from the MSDN article The LINQ Project (


To complete the MySQL treatment, it s important to know how we can use LINQ with this database. First, we must find a good LINQ provider for MySQL. DbLinq ( is the linq to SQL for other databases, including MySQL, PostgreSQL, Oracle, etc.; you can download the latest version of this provider from


With DbLinq, developers tried to reply to Microsoft s LINQ to SQL article (, which states LINQ to SQL is a component of .NET Framework version 3.5 that provides a run-time infrastructure for managing relational data as objects. To get started, you must unzip the accompanying download file in to a folder of your host machine. You ll find the complete DbLinq Visual Studio solution with tests, sources, and a build folder where you can find all the programs and assemblies to get started.


We must add a stored procedure to the world database inside MySQL to see a live sample. Using the root user, create a new empty document, edit with gedit, and paste in the following script:



CREATE PROCEDURE spSelCountries(populat int(11))


SELECT * FROM Country WHERE Country.Population < populat;



Save the file as worldSP.sql, then open a command shell and go to the just-saved file s folder; call the MySQL monitor, typing the following command:


mysql -u root -p


Now, to create the new stored procedure, simply type the commands shown in Figure 10.


mysql> use world

Database changed

mysql> delimiter "/";

mysql> source worldSP.sql

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.01 sec)

mysql> exit


Figure 10: Create a new stored procedure from the worldSP.sql file.


Now we must build an object representation of the world database; come back to your host machine and open a command prompt on the DbLinq build folder. Run the following command:


DbMetal.exe -Provider:MySql -database:world

 -server: -user:lama -password:lama

 -namespace:worldDB -code:worldDB.cs -sprocs


This command will create a new C# file containing the LINQ structure of the world database. As you can see, you must pass the following parameters: database vendor (MySQL), database name (world), server address (in this sample:, user and password to access the world database (lama), the namespace under which will fall the new classes (worldDB), and the filename to create (worldDB.cs). The last parameter (-sprocs) tells the DbMetal tool to extract the procedures, as well. Once we ve created a C# object representation, we can use it to create a class library inside the Web application s solution. Once we ve created a new project (worldLINQ in the support file), we must add references to the following assemblies:







The LINQ interaction page is contained inside the worldLinq.aspx page in the support files. This page is similar to the first we saw; there is a GridView control in the declarative file it will be bound to a data source created from the LINQ representation of data. To make a better sample, we can add a text box where the user can insert a value (Population) to filter data.


The most interesting part of this page is the GetAllRows private method you can find in the worldLinq.aspx.cs code-beside file (see Figure 11).


private DataSet GetAllRows(int inPopulation)


 string connString = System.Configuration.


 DataSet ds = new DataSet();



 // Build the connection to the database

 MySqlConnection dbcon = new MySqlConnection(connString);

 // Create the LINQ object for the world DB

 World db = new World(dbcon);

 // Calls a stored procedure

 ds = db.SpSelCountries(inPopulation);


 //catch { }

 catch (Exception ex)


 lblSysMess.Text += ex.Message;


 return ds;


Figure 11: Fill a DataSet with a LINQ object.


As in the first sample, we establish a connection to the MySQL database, then we pass the connection object (type MySqlConnection) to the constructor of your LINQ representation (World db). Now we can interact with data using the infrastructure that was built by the DbMetal tool. Note that we can call a stored procedure (SpSelCountries) with a method call (db.SpSelCountries(inPopulation)). Before compiling the worldLinq.aspx page, remember to add the following references:






To test all this, simply publish the Web application, copy all the files inside the Linux folder, and surf the page. Figure 12 shows the grid filled with data from your LINQ object; retrieved are those countries with a population less than 100,000, ordered by surface area.


Figure 12: A GridView control that binds to a LINQ source.


Even if here it is not possible to deal with all the advantages and disadvantages of using a LINQ-oriented approach versus a data-access approach, of course it is useful that you begin learning about the LinqDataSource Web server control that is still supported on Windows and it will be (may be on 2.4 version) on a future version of Mono. Start your reading with LinqDataSource Web Server Control Overview (; you ll find a lot of advantages to using LINQ in your ASP.NET applications.



In this article you learned how to run your ASP.NET Web applications inside a Linux environment. You built the LAMA stack, which is a new version of the LAMP stack that is a solution stack of software, usually free and open source, used to run dynamic Web sites or servers composed of Linux, Apache, MySQL, and PHP (or Perl or Python). In this new version you used ASP.NET as the development language. You saw that you can build your solutions on your preferred IDE (probably Visual Studio) and simply copy your files (assemblies included) to your Linux server. Of course, you must deal with a new environment, so you must learn how to manage a Linux server, an Apache Web server, and a new database like MySQL (you also can use PostgreSQL or SQLite, etc.). You also saw that you can even use LINQ on Linux but this is just the beginning.


Source code accompanying this article is available for download.


Oscar Peli is a .NET Solution Architect and director of mobile devices development at the Municipality of Ancona (Italy). As a consultant, he developed at the University of Macerata a specialized content management system to support research projects (, He is the creator of the Second Life Extender portal that offers advanced services on Second Life ( You may contact Oscar at mailto:[email protected].




Hide comments


  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.