Tuesday, December 20, 2011

In these days I have been working on a multicast streaming server that will run on a Linux box and needs some kind of web frontend. Being a seasoned ASP.NET MVC supporter I naturally picked Mono to run an ASP.NET website on Apache. A combination that — unbelievable, I know — works remarkably well!

Mono on Apache

I started with a vanilla Ubuntu 9.10 install (Karmic Koala), with comes with no Mono and no Apache server. I installed the following packages:

mono-complete (probably overkill, but better go sure),

Synaptic will magically figure out the dependencies by itself.
Update Mono

Unfortunately the Ubuntu 9.10 repositories only include Mono 2.4, which isn't the latest version available. If you want to use ASP.NET MVC (which I suggest, because it's new and shiny!) you need to install a newer version.

In order to do that, go to the Mono downloads page and get the latest Mono SVN package. Unpack the source code, launch
./configure --prefix=/usr
resolve all missing dependencies and then make and sudo make install.

Be warned that this will build the new Mono and brutally install it over the one installed through the synaptic package manager. It works, but it's ugly (and will probably come back to bite you later :)).
Setup Apache

Now that Apache (and Mono) is installed, we need to check if Apache is alive and well. Open firefox and browse to localhost.

Apache running correctly.
Greeting from your merry Apache server.

If Apache responds, we can happily go on (otherwise, try launching sudo service apache2 start to start the apache2 service).
Load the Mono modules

So, first of all we need to enable the Mono module in Apache, otherwise the server won't know how to serve our precious .aspx pages. To do so, open the terminal again and write:

sudo a2enmod mod_mono_auto
sudo service apache2 restart

This should load the module and restart the server. Try to create a simple new test.aspx page in /var/www (the default root web folder) and paste the following code in:

<%@ Page Language="C#" Inherits="System.Web.Page" %>

Hello world

Hello from Mono!

The time is <%=DateTime.Now.ToString() %>.

Server variables:

<% foreach (var var in Request.ServerVariables.AllKeys) { %>
<%=var %>

<%=Request.ServerVariables[var] %>

<% } %>

Fire up Firefox again and check out the page. If Mono spits out a very nice page with a whole lot of HTTP server variables, the server is ready. In fact, thanks to a mechanism called AutoHosting, Mono doesn't require any further configuration if you use ASP.NET as a simple scripting engine (like you would use PHP for instance).

If instead you need to setup a complete ASP.NET application (which is the case for MVC apps, with routing and all), you have a bit more of configuration to do.
Install an ASP.NET application

This time we'll need to edit the /etc/apache2/http.conf configuration file to add a new virtual application that will be entirely handled by our beloved Mono runtime. Luckily there's a simple little script online that does all the work for us: the mod-mono configurator.

Tell the script that you are installing an ASP.NET Application and input the application's name and physical path. Simply put, an application's name is the virtual folder on the server on which the application will be served (for instance, at The physical path is the root directory of your ASP.NET application files (usually somewhere under /var/www/, but it could be anywhere).

Check/uncheck the remaining options and then create the configuration file. Copy its contents and paste them in your /etc/apache2/http.conf. Save the file, restart Apache aaaand... off you go with your ASP.NET application running on Mono and served by Apache. ;)
But I need an ASP.NET MVC application!

No problem, in fact, hardly anything changes. Just two suggestions: do not attempt to include the Microsoft.Web.Mvc.dll library. It contains a lot of useful and nice stuff, but isn't compatible with Mono right now (you can still take out the code you need and put it in a custom library).

And secondly, since most URLs of ASP.NET MVC are extensionless, you need to tell Apache that everything must be handled by the Mono runtime (and thus go through the MVC routing system). To do so, create a .htaccess file in your application's root folder with the following line:

ForceType application/x-asp-net

This will force Apache to serve all pages through ASP.NET. Hope this works for you! :)

No comments: