Skip to content


Running a C# Web Service on Linux: Mono, XSP and mod_mono

Recently, I’ve shifted my focus away from a pet XNA project in favour of another iPhone application that we’ve started developing. I wanted to get up and running quickly with the back-end web service, so given my recent experience with C#, it seemed a natural choice to go with ASP.NET and Visual Studio 2008. We run a Linux server, so I figured this would be the perfect opportunity to test out the Novell funded Mono project.

I did a little bit of research and was delighted to find that Mono comes with its own IIS-compatible, XSP. Mono project also provides mod_mono, an Apache plug-in which allows ASP.NET pages to run alongside PHP webpages, like those already on our server. Everything looked all peachy so before I decided to install Mono, mod_mono and XSP on our Linux box, I thought I would write and debug the back-end locally with Visual Studio 2008 and IIS. Our Linux box has MySQL up and running, so I decided to run the database on the server and connect to it remotely. In order to do so I downloaded the .NET MySQL Connector. Once again, I was happy to hear that the connector was Mono compatible.

The first step was to SSH into our Linux box and add a new MySQL user and database for use by my C# web service. After doing this, I became aware of just how well the MySQL .NET Connector integrates into the Visual Studio 2008 IDE. I was able to add our Linux box to the list of remote servers with ease. However, it was here that I encountered my first minor hiccup; our Linux box was refusing the connection from Visual Studio.

It turns out that by default CentOS 4 doesn’t leave port 3306 open for remote connections. To fix this I did the following:

iptables -A INPUT -i eth0 -p tcp –dport 3306 -j ACCEPT

Where eth0 is our Internet-facing network port. I was able to verify that this opened up the port, but one also needs to add a line to MySQL’s configuration file, usually in /etc/my.cnf.

bind-address=YOURIP

‘YOURIP’ should be replaced by the IP address of the machine running MySQL. After doing this you will need to restart MySQL:

service mysql restart

Okay, so that made short work of that little issue, so from here I was free to get to work on the web service functionality. Having never done any C# web programming before, I was very impressed with how little time it took me to setup a SOAP compliant web service. .NET automatically generated scaffolding that allowed me to test the functionality of my web service directly from my browser.

Once I was satisfied with my C# web service, it was time to get it running on our Linux server. First off was the installation of Mono, mod_mono and XSP. Mono project doesn’t provide CentOS (or RHEL) binaries, so I had to compile Mono, mod_mono and XSP from source, using the following commands.

wget http://ftp.novell.com/pub/mono/sources/mono/mono-2.4.2.3.tar.bz2
wget http://ftp.novell.com/pub/mono/sources/xsp/xsp-2.4.2.tar.bz2
wget http://ftp.novell.com/pub/mono/sources/mod_mono/mod_mono-2.4.2.tar.bz2
tar -vxjf mono-2.4.2.3.tar.bz2
tar -vxjf xsp-2.4.2.tar.bz2
tar -vxjf mod_mono-2.4.2.tar.bz2
cd mono-2.4.2.3
./configure
make
make install
cd ..
cd xsp-2.4.2
export PKG_CONFIG_PATH=/usr/lib/pkgconfig
./configure
make
make install
cd ..
cd mod_mono-2.4.2
./configure
make
make install

The compilation and installation were both pretty smooth, although I did encounter my pet hate; warnings, hundreds of warnings! Okay, I’m glad they weren’t errors but GCC doesn’t give warnings because it likes to torment developers, there’s usually a good reason for them. After dealing with that little bit of grief, I assumed I’d have to also compile the MySQL .NET Connector on the Linux box itself. Before doing so, I thought I’d just try use the Windows binary that I had downloaded from the MySQL website. Certainly seems like a little bit of a strange thing to do, but I knew Mono were aiming for binary compatibility so I thought I’d give it a shot. I started up WinSCP and copied across the DLL into the mono version 2.0 library directory /usr/lib/mono/2.0/. Then I registered the DLL with Mono by doing the following:

cd /usr/lib/mono/2.0/
gacutil -i mysql.data.dll

Mono didn’t seem to complain, so it looks as though my efforts (or perhaps lack thereof) were rewarded. Of course I tested the functionality later — trust me, it does work! It was here that I realised I’d forgotten the final stage of setting up mod_mono. The default mod_mono functionality was enough for what I wanted to achieve, so I just needed to make a small addition to Apache’s httpd.conf file to include mod_mono. Add the following lines somewhere near the bottom of your httpd.conf file:

Include conf/mod_mono.conf
MonoServerPath /usr/bin/mod-mono-server2

After doing this you’re going to need to restart apache so it reloads the conf files. Next, it was time to SCP across my webservice code and the precompiled DLL to test out the functionality on our Linux box. First, I modified my code slightly so that my webservice would connect to the MySQL database via ‘localhost’ instead of using port 3306. Then I made sure this would work by removing the remote MySQL user and adding a new localhost user.

Okay, now I had the binaries and code located in a directory on my server. Trying to access them gave me my next little headache. When I accessed the URL, Mono gave an error stating that it couldn’t find my web service class. I originally assumed that the inclusion of code-behind in my asmx file was enough to get things working. Apparently, both XSP and IIS ignore this parameter; Visual Studio includes it for no other reason than because “it can”. After a lot of tinkering around, trying to get the binaries and code working, I stumbled across two solutions for my problem.

  • Place all the code from all my classes in the one asmx file.
  • Place the code and/or binaries in my root url directory.

If you remember earlier on, I stated that I’d placed my web service in a sub-directory on my server. XSP (and perhaps IIS) don’t seem to like this by default. XSP was looking for my source and binaries in the wrong spot! The first solution was not very desirable as it would make maintenance a nightmare. Solution 2 certainly was a lot more desirable, and I wasn’t keen to tinker around with the XSP/mod_mono settings, so I left it at that. After doing this I also was happy to find that I was able to delete the source code altogether and just leave my previously compiled DLL.

Finally, I had a working C# web service running on a Linux server, hurray! Shortly, you’ll get some more information about the iPhone application that makes this server useful, so stay tuned!

Posted in Devblogs.

Tagged with , , .


0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

You must be logged in to post a comment.