Running VS Code on Linux

Curtsy/ Original post: https://code.visualstudio.com/docs/setup/linux

Running VS Code on Linux

Installation

  1. Download Visual Studio Code for your distribution, .deb for Debian-based distributions such as Ubuntu or .rpm for Red Hat-based distributions such as Fedora or CentOS. Note that 32-bit binaries are also available on the download page.
  2. Install the package through a GUI package manager by double clicking on the package file, or through the command line:
 # For .deb
 sudo dpkg -i <file>.deb
 # install dependencies
 sudo apt-get install -f

 # For .rpm (Fedora 21 and below)
 sudo yum install <file>.rpm

 # For .rpm (Fedora 22 and above)
 sudo dnf install <file>.rpm
  1. VS Code should now be available to run through the launcher or the command line by running code.

Tip: Run code . in any folder to start editing files in that folder.

Note:

Visual Studio is tightly integrated with Windows and Developing a .NET application using any language (C# or VB) takes more than just having Wine, and since Wine is not capable enough to provide complete development runtime as .NET in Linux.

If you want to develop software specifically in C#, on Linux, you can use MonoDevelop

Since, you’re asking for Visual Studio 2010 (.NET 4.0), with MonoDevelop, you’ll not be able to develop an app that particularly uses .NET 4, as of now MonoDevelop is in version 3.0.2 (somewhat equivalent to .NET 3.0).

You can still use Windows virtually within Ubuntu, using VirtualBox. And then install Visual Studio there, but still a serious app development is not recommended to be done in Virtualized environment.

Download Visual Studio Code

https://code.visualstudio.com/download

http://www.monodevelop.com/download/

 

Advertisements

ASP.NET Apache setup on CentOS

Original Post: http://jharitesh.blogspot.com/2012/06/aspnet-apache-setup-on-centos.html

ASP.NET Apache setup on CentOS

To run ASP.NET application on Apache mod_mono module should be installed and configured on Apache.
All .NET pages are actually processed by mono which runs in background along with Apache. Apache identify .Net request page with help of mod_mono module. I used centOS as OS and performed following steps to run ASP.NET application on Apache.

  • Mono installation
  • XSP installation
  • Apache installation
  • mod_mono installation
  • Configuration

Mono installation

  1. yum install gcc bison pkgconfig glib2-devel gettext make 2. Please check latest mono version on site before installation and edit command with latest version.  wget http://ftp.novell.com/pub/mono/sources/mono/mono-2.10.2.tar.bz2 3. tar jxvf mono-2.10.2.tar.bz2 4. cd mono-2.10.2 5. ./configure -prefix=/opt/mono; make; make install 6. echo export PKG_CONFIG_PATH=/opt/mono/lib/pkgconfig:$PKG_CONFIG_PATH>>~/.bash_profile 7. echo export PATH=/opt/mono/bin:$PATH>>~/.bash_profile 8. source ~/.bash_profile 9. mono -V

to check mono is installed or not

  1. cd ..

XSP installation

  1. wget http://ftp.novell.com/pub/mono/sources/xsp/xsp-2.10.2.tar.bz2 2. tar jxvf xsp-2.10.2.tar.bz2 3. cd xsp-2.10.2 4. ./configure -prefix=/opt/mono; make; make install 5. cd ..

Apache installation

  1. yum -y install httpd-devel

mod_mono installation  

  1. wget http://ftp.novell.com/pub/mono/sources/mod_mono/mod_mono-2.10.tar.bz2 2. tar jxvf mod_mono-2.10.tar.bz2 3.  cd  mod_mono-2.10 4. ./configure –prefix=/opt/mono; make; make install 5. cd ..

 Configuration

  1. mono_setup configuration: create mono_setup.conf under directory /etc/httpd/conf.d with below content.

Include /etc/httpd/conf/mod_mono.conf

MonoApplications “/:/var/www/html/”

MonoServerPath “/opt/mono/bin/mod-mono-server2”

Options FollowSymLinks

AllowOverride None

AddHandler mono .aspx .ascx .asax .ashx .config .cs .asmx .axd

  1. Apache configuration: 

1) Open /etc/httpd/conf/httpd.conf and uncomment below line(remove ‘#’).

NameVirtualHost *:80

Extra setting:

I like Ubuntu way to enable disable site so I added this in here too.

2) Add below line

Include /etc/httpd/sites-enabled/

3) Create two directory inside /etc/httpd using below command

mkdir /etc/httpd/sites-enabled
mkdir /etc/httpd/sites-available

4) Type following to create new file a2ensite
    1) cat > a2ensite
2) Type this line
ln -s /etc/httpd/sites-available/$1.conf   /etc/httpd/sites-enabled/$1.conf

3) Press enter to move cursor to a new line and press CTRL+D.
4) Type this  command to make a2ensite executable
chmod   +x   a2ensite
5) Copy into /usr/bin
cp a2ensite /usr/bin

Type following to create new file a2dissite
    1) cat > a2dissite
2) Type this line
rm       -f          /etc/httpd/sites-enabled/$1.conf

3) Press enter to move cursor to a new line and press CTRL+D.
4) Type this  command to make a2ensite executable
chmod   +x   a2dissite
5) Copy into /usr/bin
cp          a2dissite         /usr/bin

3.Config application

Each application will have own separate config in directory  /etc/httpd/sites-available
sample application config file: file path is /etc/httpd/sites-available/name.xyz.com

    ServerAdmin xxxx.yyy@name.xyz.com

DocumentRoot /var/www/name.xyz.com

DirectoryIndex Default.aspx

ServerName name.xyz.com

ServerPath /

MonoAutoApplication disabled

MonoApplications “/:/var/www/name.xyz.com”

MonoServerPath “/opt/mono/bin/mod-mono-server2”

AddHandler mono .aspx .ascx .asax .ashx .config .cs .asmx .axd

ErrorLog /var/log/httpd/ name.xyz.com-error_log

CustomLog /var/log/httpd/ name.xyz.com-access_log common

 

In sample config application root directory is var/www/name.xyz.com i.e all application files will be kept in folder name.xyz.com.

4. Deployment 
    1) create directory /var/www/name.xyz.com
2) Copy application folder content into directory /var/www/name.xyz.com
3) Type below command to enable web-application in apache

#a2ensite name.xyz.com

#service apache2 restart
4)  Type below command to disable web-application in apache.
#a2dissite name.xyz.com

#service apache2 restart
Note: file name should be same as what we create in /etc/apache2/sites-available.

5) Other useful commands
To start apache  #service httpd start
To restart apache #service httpd restart
To stop apache #service httpd stop
To check mono is running in background or not  #ps -ef |grep -i “mono”

I also came across few issues during setup and got good solution from other forums. Here are collectively all issues.

  1. After deployment & restart of apache when we try to access page ….it is shown as blank page.

Apache error log contains following errors:

[crit] (2)No such file or directory: Failed to create shared memory segment for backend ‘testing’ at ‘/var/run/mod_mono/mod_mono_dashboard_testing_2’.

It is actually thrown because it is failing to create shared memory. Mono run as user apache but only root can write to /var/run. So solution is to create a folder and make apache owner.

  1. After solving 1st error when we try to access page from browser it throws error “Service Temporarily Unavailable”. In apache error log below error is shown.

” [error] Failed to connect to mod-mono-server after several attempts to spawn the process.”

solution: This is because of SELinux. By disabling SELinux using following command this issue can be resolved.

# setenforce 0

Script for above two issue is as follows.

dir=”/var/run/mod_mono/”

echo “Disable SELinux”
setenforce 0
echo -n “SELinux status is ”
/usr/sbin/getenforce
echo “Stopping Apache”
apachectl stop
echo “Waiting 5 seconds”
sleep 5s
shopt -s dotglob
if [ -d “$dir” ]; then
echo “Removing $dir”
rm -rf “$dir”*
rmdir “$dir”
fi
echo “Creating $dir”
mkdir “$dir”
echo “Changing owernerhip of $dir to Apache”
chown apache “$dir”
chgrp apache “$dir”

chown             -R apache   /opt/mono/
mkdir   -p        ~apache/.mono
chown  -R        apache:apache    ~apache/.mono
chmod             u+rw    ~apache/.mono
echo “Starting Apache”
apachectl start
echo “Done!”

Above script will run only when system start or reboot.

  1. Error message “Make sure that your mod_mono module is loaded after the User/Group directives” is thrown when we start/restart apache. [1]

soln : Put below statement just above “Include conf.d/*.conf” in httpd.conf

User apache
Group apache

and then restart apache httpd service.

  1. Error message ” Starting httpd: httpd: Could not reliably determine the server’s fully qualified domain name, using localhost.localdomain for ServerName”

Do following
1) Edit /etc/hosts using your favourite editor The contents should look something like this: # Do not remove the following line, or various programs # that require network functionality will fail. 127.0.0.1 localhost.localdomain localhost ::1 localhost6.localdomain6 localhost6
2).
At the end of the file add: 192.168.20.100 Server1.example.com That’s a [tab] between the IP address and the host name.
3) Save the file
4) Restart the network services to apply your changes service network restart
5)
Restart Apache service httpd restart

  1. Error message “Auto generated encryption keys not saved: System.Security.SecurityException: No access to the given key”

Reason :ASP.NET is creating auto generated keys for the machine and failing to safe them. The only problem, other that seen that message, is that every time the application is started it will get new keys because they are not being saved.

The directory where this is trying to write is somewhere $SYSCONFDIR/mono/registry (usually /etc/mono/registry). If it allow the user running apache read, write, and execute permissions on that folder, Mono will be able to save the auto generated keys and will reuse them subsequently. Once the keys are written, the apache user will only need read and execute permission.

Solution:
chown             -R apache /opt/mono/
mkdir   -p        ~apache/.mono
chown  -R        apache:apache  ~apache/.mono
chmod             u+rw  ~apache/.mono

The auto-generated keys are now being stored at: “/var/www/.mono/registry/”

Introduction to Mono – ASP.NET with XSP and Apache

Original Post: http://www.codeproject.com/Articles/9738/Introduction-to-Mono-ASP-NET-with-XSP-and-Apache

Introduction

This article is the second article in the series of introductory articles that I am writing about Mono, the “open source development platform based on the .NET framework”. In this article we’ll take a look at how to get going with ASP.NET on the Mono platform. Although ASP.NET is not part of the ECMA and ISO standards mentioned in the first article[^], it is still one of the major selling points of the .NET platform and provides an extremely flexible and powerful platform for developing web applications and Web Services upon. Although you can develop ASP.NET applications for Mono on a number of different operating systems this article will focus mainly on Linux, although, in saying that, I do look briefly at getting XSP running on Windows. The reason I will concentrate on ASP.NET on Linux is because those people interested in ASP.NET on Windows have an extremely powerful option at their fingertips in the form IIS and I would whole heartedly recommend using it for ASP.NET on Windows.

Where does ASP.NET stand with Mono??

The latest stable version of Mono, version 1.0.5, has a fully functional implementation of ASP.NET. This includes full support for ASP.NET Web Forms and Web Services. This essentially means that more or less any ASP.NET application that you have developed using with the .NET Framework will work with Mono. Obviously there might be changes needed, such as data access changes, removal of any reliance on .NET Framework BCL types that are not implemented in Mono yet, and also the removal of any code that makes use of platform invoke and so on. At this stage the ASP.NET support in Mono can be considered as excellent and a lot of publicly available web applications already make use of Mono’s ASP.NET support. According to the Mono site the Mono Web Services stack is being used in the source control application Vault[^] by SourceGear and aspects of Mono’s ASP.NET implementation are also used in the Virtuoso[^] product from OpenLink.

What are XSP and mod_mono?

There isn’t much point in developing web applications and Web Services if you have no way of serving them, is there? Traditionally you would use IIS to host ASP.NET applications on Windows, although there are some other free ASP.NET web servers available such as Cassini[^]. However, when using ASP.NET with Mono you have two main options as regards which web server to host your ASP.NET applications in:

  • XSP
  • Apache

In this article we look at using both XSP (on Windows and Linux) and Apache to host your ASP.NET web applications and Web Services.

XSP

XSP is a “light-weight web server” capable of hosting and serving ASP.NET applications. It is written using C#, making extensive use of the classes in the System.Web namespace, and the source for XSP is available for download from the Mono download page[^] . It is also interesting to note that the XSP web server runs on both the Mono runtime and also on the .NET runtime which means that if you are looking for a light-weight ASP.NET web server for Windows but you don’t want to use or you don’t care about Mono, you could still make use of XSP. The Let’s get XSP up and running section runs through how to install and use XSP on Windows and Linux.

Apache

Apache is probably the de facto standard web server used on Linux. Apache makes extensive use of modules to enable it to host and serve web applications developed in a multitude of different web programming languages and scripts. Those of you familiar with IIS but not so familiar with Apache can think of these modules as the equivalent of ISAPI extensions. So, by this stage I assume you can guess how Apache can host and serve ASP.NET application? Yep, using an Apache module. This module, called mod_mono, allows Apache to serve ASP.NET pages “by proxying the requests to a slightly modified version of XSP called mod-mono-server”. mod-mono-server is installed when you install XSP. At the time of writing the current version of the mod_mono module for Apache only works for Apache on Linux and not for Apache on Windows. For this reason, when we look at ASP.NET on Apache in the Apache with mod_mono section we only look at it in the context of Linux. If you do wish to serve ASP.NET content from Apache on Windows have a look at this article[^] on CP, which shows how to use configure Apache to use Cassini to serve ASP.NET content or have a look at the Apache HTTP CLI[^] project.

What you need to know

This article assumes that you have Mono installed and working on your desired platform. The first article in this series, Introduction to Mono – Your first Mono app[^], explains how to get Mono up and running on Windows and Linux so if you have not yet done so have a look over that article. I also assume that you are familiar with ASP.NET and the semantics of ASP.NET programming as this article primarily looks at getting ASP.NET working with XSP and Apache, not at ASP.NET programming.

Lets get XSP up and running

In this section we will look at getting XSP up and running on both Windows and on Linux. Installing and running on Windows is “tackled” first simply because I want to get it out of the way and because chances are that you already have XSP on Windows considering the fact that you should have Mono already installed. Then it’s on to Linux and getting XSP up and running there. To be honest, if you already have Mono running on Linux, which you should as it’s one of the prerequisites for this article, then it should be relatively easy.

XSP on Windows

The first article[^] in this series ran through installing Mono on Windows. It mentioned that during the install process the installer gives you the option to select which components to install. By default, XSP is installed along with Mono but if you decided to not install XSP during the install then the easiest way to get XSP installed is to uninstall Mono and then reinstall it again. Here are the steps explaining how to install Mono and XSP on a Windows 2000 or above machine:

  1. Download the Mono Windows Installer from the Mono download page. The file I am working off is http://www.go-mono.com/archive/1.0.5/windows/mono-1.0.5-gtksharp-1.0.5-win32-0.1.exe
  2. The installer is a standard Windows installer so you can simply run it once it is downloaded by doubling clicking on it.
  3. Once the installer begins, click on next to go to the License Agreement page.
  4. You’ll probably notice on the License Agreement page that there are a number of different Licenses that apply to the different components of the install. While I understand that most people simply agree and click on next, it would be irresponsible of me if I didn’t recommend that you read the License Agreement before agreeing to it.
  5. Once you pass the License Agreement section you are presented with some general information about the install.
  6. Click on Next and select the install location.
  7. Click on Next again to bring you to the Select Components page. You are free to customize your installation but make sure that you install XSP. As I will be using all the components of this install in other articles in this series I would suggest that you accept the default “Full installation”.
  8. Click on Next again and you can customize the name of Mono folder that appears in the Start Menu.
  9. The installer will now ask you which port you want the XSP web server to listen on. Generally this will be port 8088 but you can change it to any free port on your system. When you are ready click on Next.
  10. Finally, click on Install to install and configure Mono and XSP on your Windows machine.

Those of you who read the first article will notice that I more or less ripped the instructions from that one… I’m not lazy, just no point in rewriting what has already been said! The next step in using XSP on Windows is to run it. The Running XSP section explains how to run the XSP web server and looks at some of the command line options that you can use to alter it’s default behaviour.

XSP on Linux

As with installing Mono on Linux, which we examined in the previous article, things are slightly more complicated on Linux then on Windows. However, as I already mentioned, if you have Mono installed, then getting XSP installed is going to be a breeze for you. I’m installing XSP on the same systems that I used for installing Mono in the previous article. A quick recap of what exactly I used is in order so: I used Microsoft Virtual PC 2004 and created two identical virtual PCs. I then installed SuSE 9.2 Professional with ACPI disabled and I used the default package selection when installing. In the last article I went through how to install Mono using the pre-built packages from the Mono site and also I ran through how to install Mono from source. So for the purposes of this article I will be installing XSP on a SuSE 9.2 Professional with the default package selection with Mono 1.0.5 installed along with any additional packages or programs that were installed during the Mono install.

In this article we will again look at installing from both the pre-build packages and from the source.

XSP using pre-built packages

As I am sure you can remember from the first article (if you read it that is), installing using the pre-built packages from the Mono site is one of the easiest ways of getting Mono up and running. The same thing applies to getting XSP up and running. So, head on over to the Mono download page (http://www.mono-project.com/downloads/index.html[^]) and see if there are pre-built packages for your particular Linux distribution or if there are packages for a distribution that you know will be compatible with your distribution. If there isn’t a package that will work with your distribution just jump ahead to the XSP from source section where I will run through installing XSP from the source which is a simple process.

Lets get going:

  1. On the Mono download page, click on the “Packages” link beside the Linux distribution that you believe to be compatible with your distribution. I simply selected the link beside SuSE 9.2
  2. This should bring you to a page which lists a lot of different packages that have been compiled and packaged for that particular Linux distribution.
  3. Before we install XSP we need to install two other pre-built packages. These packages include files that XSP is dependent upon.
  4. The first package we need to install is the “Database Core” package that can be found in the database section. The exact name of the package will vary depending on the packages link that you selected initially but in general the name will start with “mono-data”. The package I downloaded for SuSE 9.2 was http://www.go-mono.com/archive/1.0.5/suse-92-i586/mono-data-1.0.5-1.ximian.10.4.i586.rpm.
  5. Once you have downloaded this file, open it and it will launch the package manager for your distribution. At this stage simply follow the instructions to install the package.
  6. After you have installed the “mono-data” package you now need to download the “mono-web” package which will be listed under the “Web Applications, Web Services” section. The package I downloaded for SuSE 9.2 was http://www.go-mono.com/archive/1.0.5/suse-92-i586/mono-web-1.0.5-1.ximian.10.4.i586.rpm.
  7. Next, as with the “mono-data” package, simply open the package and follow the instructions to install it using the package manager of your distribution.
  8. Finally we are ready to install XSP itself. So just head back to the “Web Applications, Web Services” section of the package download page and download the “xsp” package. The package I got was http://www.go-mono.com/archive/1.0.5/suse-92-i586/xsp-1.0.5-1.ximian.10.1.i586.rpm.
  9. As with the two previous packages, simply open it and follow the instructions of your package manager to install XSP.
  10. All going well, you should have XSP installed now!

At this stage XSP should be installed on your system so you can jump ahead to the Running XSP section which gives an overview of how to use XSP. If you are having difficulty installing XSP from the packages have a look at the next section, “XSP from source”, which might be able to help you out.

XSP from source

Installing XSP from the source should be breeze if you have installed Mono from source by following the instructions in the previous article[^]. Let’s jump straight in:

  1. The first thing you need to do is download the source. Once again, head on over to the Mono download page at http://www.mono-project.com/downloads/index.html[^].
  2. In the source code section click on and download the “XSP web server”. I downloaded http://www.go-mono.com/archive/1.0.5/xsp-1.0.5.tar.gz.
  3. Once the file has been downloaded, go to a console for the remainder of the process
  4. You can decompress the downloaded file using the command tar -xvzf xsp-1.0.5.tar.gz where xsp-1.0.5.tar.gz is the name of the file you downloaded.
  5. Next, switch to the directory where the source code has been decompressed to by typing cd xsp-1.0.5 or cd followed by the name of the directory that you decompressed the file to if it is different from mine.
  6. Now, before we can compile the source you need to configure the make files. To do this simply type ./configure --prefix=/usr. This will take a bit of time. I am assuming here that there were no errors and that the ./configure --prefix=/usr went ahead without issue.
  7. When the the ./configure --prefix=/usr completes you are free to go ahead and compile and install the source.
  8. To actually compile the XSP source you need to run the make command.
  9. Root privileges are required for the next step. If you have just installed Linux as a standalone machine you can usually give your account root privileges by typing the sudo bash command and entering the root password.
  10. Finally, to install, for lack of a better word, simply run the make install command. This will deploy the compiled binaries, libraries and other bits and pieces to the correct directories.

Congratulations. You should not have the XSP web server installed on your system. The next section looks at how to run and use the XSP web server.

Running XSP

XSP should be installed on your preferred platform at this stage so now we will look at how to start XSP and we will also look at the different command line options you can use to modify the default behaviour of the server.

Running XSP ASP.NET Examples

Starting XSP with the ASP.NET examples that come with it is a bit of a no-brainer on both Linux and Windows, well, it is with the version 1.0.5 of XSP that I am using:

  • Starting XSP examples site on Windows
    • Simply go to to the Mono folder in the Programs or All Programs section of your Start Menu. For example, on my machine the Mono folder in the All Programs folder on the Start Menu is called Mono 1.0.5 for Windows.
      In this folder, go to the XSP subfolder and then click on XSP Test Web Server.
  • Starting XSP examples site on Linux
    • Starting the XSP server with the default settings on Linux is easier again. Simply change directory to the directory where the ASP.NET examples are installed using the command cd /usr/share/doc/xsp/test/ (this assumes that you have installed XSP in the /usr diretory).
      Now, to start XSP with the ASP.NET examples simply use the command xsp which will start XSP using the default settings.

On both Windows and Linux you should get output similar to the following on your screen:

Listening on port: 8080
Listening on address: 0.0.0.0
Root directory: /usr/share/doc/xsp/test
Hit Return to stop the server.

The above output is from starting XSP on Linux using the steps above. The main difference you will notice in the output from Windows is that the port that the server is listening on will probably be port 8088, which is the default port used by the Mono installer on Windows. You will also notice that the Root Directory will probably be something like C:\PROGRA~1\MONO-1~1.5\share\doc\xsp\test.

Regardless of the output, if XSP has started successfully simply fire up your browser and point it to http://localhost:<port num> where <port num> is the port number that is listed at the end of the the Listening on port: line of the output. On Linux you would generally use http://localhost:8080 and on Windows you would use http://localhost:8088. When the browser loads you should be presented with a web page similar to the one shown in Figure 1 below.

XSP web server on Linux showing ASP.NET examples pages.
Figure 1: XSP web server on Linux showing ASP.NET examples pages.

The page shown in Figure 1 is the home page of the example ASP.NET site that comes with XSP. It has numerous examples of ASP.NET Web Forms and ASP.NET Web Services.

XSP, close up.

The information in the section above shows how to start the examples website that comes with the XSP web server. However, chances are high that you will want to use the web server for actually serving your own web applications and Web Services. To this end we will now look at the command line options that you can use to modify the default behaviour of XSP. However, before doing that I want to point out where the XSP web server itself is located on both Linux and Windows:

  • Windows
    • <Mono install dir>\lib\mono\1.0\xsp.exe
      On my installation, a default Mono install, this relates to: C:\Program Files\Mono-1.0.5\lib\mono\1.0\xsp.exe

      I would recommend adding the directory <Mono install dir>\lib\mono\1.0\ to your path in Windows as this will allow you to start the XSP web server by typing xsp.exe at the command prompt. You should note however that if you do start XSP in this manner you will actually be running it on the .NET runtime and not on the Mono runtime… a good example of Mono – .NET interoperability.

  • Linux
    • <Mono install dir>/lib/mono/1.0/xsp.exe
      On my installation, using the instructions in the XSP on Linux section above, this related to: /usr/lib/mono/1.0/xsp.exe

      Note that on Linux the installation also places a script <Mono install dir>/bin/xsp that can be used from the console to start XSP. This is the command I used in the section above to start the XSP examples web site. When you type and run xsp at the console you are actually running the command mono /usr/lib/mono/1.0/xsp.exe

Now, on to the command line options for XSP, or to be more exact, for xsp.exe:

Option
–port N N is the tcp port to listen on.

Default value: 8080
AppSettings key name: MonoServerPort

–address addr addr is the ip address to listen on.

Default value: 0.0.0.0
AppSettings key name: MonoServerAddress

–root rootdir The server changes to this directory before doing anything else.

Default value: current directory.
AppSettings key name: MonoServerRootDir

–appconfigfile FILENAME Adds application definitions from the XML configuration file.

See sample configuration file that comes with the server.
AppSettings key name: MonoApplicationsConfigFile

–appconfigdir DIR Adds application definitions from all XML files found in the specified directory DIR.

Files must have ‘.webapp’ extension
AppSettings key name: MonoApplicationsConfigDir

–applications APPS A comma separated list of virtual directory and real directory for all the applications we want to manage with this server.

The virtual and real directories are separated by a colon. Optionally you may specify virtual host name and a port.
[[hostname:]port:]VPath:realpath,…

Samples:
/:.
the virtual / is mapped to the current directory.

/blog:../myblog
the virtual /blog is mapped to ../myblog

myhost.someprovider.net:/blog:../myblog
the virtual /blog at myhost.someprovider.net is mapped to ../myblog

/:.,/blog:../myblog
Two applications like the above ones are handled.

Default value: /:.
AppSettings key name: MonoApplications

–nonstop Don’t stop the server by pressing enter.
Must be used when the server has no controlling terminal.
–version Displays version information and exits.
–verbose Prints extra messages.
Mainly useful for debugging.

The above command line options where taken from the XSP web server itself

So, what does the above boil down to? Well, the easiest way to explain is to show some example command lines so here goes:

  • Windows: xsp.exe --port 80 --root c:\inetpub\wwwroot\
  • Linux: mono /usr/lib/mono/1.0/xsp.exe --port 80 --root /home/bdelahunty/asp.net/ --applications /:.,/articles:../documents/articles
  • Windows: mono "C:\Program Files\Mono-1.0.5\lib\mono\1.0\xsp.exe" --port 80 --root r:\WebApplications\ --nonstop

Now that we have looked at XSP it’s time to move on to getting Apache serving ASP.NET pages. If you don’t care about ASP.NET on Apache then you could always skip ahead to the Some Examples section where I run through a simple ASP.NET example.

ASP.NET on Apache with mod_mono

Apache is the web server of choice on Linux and is, according to netcraft[^], the most widely used web server on the net. This means that there are lots of websites out there that could be serving ASP.NET web applications and hosting ASP.NET Web Services. Mono makes this possible in the form of the mod_mono module for Apache which makes use of XSP or, to be more specific, it makes use of mod-mono-server.exe which is a specialized version of XSP.

In this section we will look at installing mod_mono and how to get Apache serving ASP.NET content. However, before we do that, we need to get Apache installed. As this article is aimed more at how to get Apache serving and hosting ASP.NET content I will quickly run over getting Apache installed. If you run into any difficulty when trying to install Apache just search the web for instructions on how to install Apache on your particular Linux distribution.

Oh, and one more thing. As I mentioned in the What are XSP and mod_mono? section, mod_mono currently does not work with Apache on Windows so I only look at Apache on Linux from here on.

Installing Apache

As with most things on Linux there are a number of different ways to install applications. In the case of Apache I’m just going to install from source as it is probably one of the easiest ways to install Apache and it is also the most distribution independent way of installing it that I know of. If you already have Apache 1.3.x or greater installed then you can skip ahead to the Installing and configuring mod_mono section. So, lets get Apache installed:

  1. First you will need to download the Apache source so head over to the Apache download page at http://httpd.apache.org/download.cgi[^].
  2. Download the latest version of the Unix Source for Apache. At the time of writing this article the latest version is 2.0.53. The file I downloaded was http://apache.mirrors.esat.net/httpd/httpd-2.0.53.tar.gz.
  3. Once the file has been downloaded, go to a console for the remainder of the process
  4. Decompress the downloaded file. For example, if you have downloaded the same file that I downloaded you could use the command tar -xvzf httpd-2.0.53.tar.gz as long as the file is in your current working directory.
  5. Next, switch to the directory where the source code has been decompressed to by typing cd httpd-2.0.53 or cd followed by the name of the directory that you decompressed the file to if it is different from mine.
  6. Now, before we can compile the source you need to configure the make files. To do this simply type ./configure --enable-so --prefix=/usr.
  7. When the the <CODE>./configure --enable-so --prefix=/usr completes you are free to go ahead and compile and install the source.
  8. Run the make command to compile Apache.
  9. You need to have root privileges to perform the next step successfully. If you have just installed Linux as a standalone machine you can usually give your account root privileges by typing the sudo bash command and entering the root password.
  10. Finally, to install, for lack of a better word, simply run the make install command. This will deploy the compiled binaries, libraries and other bits and pieces to the correct directories.

At this stage you should have Apache installed. To start the Apache web server type httpd at the console. You can check if Apache has started by pointing your browser to http://localhost/ where you should see a web page similar to the one shown in Figure 2.

Apache Web Server running on Linux
Figure 2: Apache Web Server running on Linux

Now that we have Apache installed it’s time to install mod_mono and configure Apache to host and serve ASP.NET content.

Installing and configuring mod_mono

Ok. We’re nearly there. Apache should be up and running by now so we don’t have too much left to do. We need to install mod_mono and then configure Apache in order to make it send the requests that we want through the mod_mono module and on to the mod-mono-server.exe application that will handle the request. As with Apache, I’m gong to run through installing mod_mono from the source. Before we actually go ahead and install mod_mono I should mention that there are some prerequisites to installing. You must have Mono installed, you must have XSP installed, and you must have Apache installed. If you’ve been following this article, and the previous article, then you should already have your system configured as needed.

Now, lets see if we can get mod_mono installed:

  1. So, once again, we need to download some source code. Head on over to the Mono download page at http://www.mono-project.com/downloads/index.html[^].
  2. In the source code section click on and download the “Apache Mono module”. I downloaded http://www.go-mono.com/archive/1.0.5/mod_mono-1.0.5.tar.gz.
  3. Once the file has been downloaded, go to a console for the remainder of the process
  4. Decompress the downloaded file using the command tar -xvzf mod_mono-1.0.5.tar.gz where mod_mono-1.0.5.tar.gz is the name of the file you downloaded.
  5. Next, switch to the directory where the source code has been decompressed to by typing cd mod_mono-1.0.5 or cd followed by the name of the directory that you decompressed the file to if it is different from mine.
  6. Now, before we can compile the source you need to configure the make files. To do this simply type ./configure --prefix=/usr .
  7. Next, to actually compile the mod_mono source you need to run the make command.
  8. The next step has to be performed using an account with root privileges. If you have just installed Linux as a standalone machine you can usually give your account root privileges by typing the sudo bash command and entering the root password.
  9. Finally, to install mod_mono simply run the make install command. This will deploy the compiled binaries, libraries and other bits and pieces to the correct directories.

That should have been painless. You should have mod_mono installed on your system now. So what’s left to do? Well, we need to configure Apache to use mod_mono to handle requests. This means we need to edit the Apache config files. If you have installed Apache following the instructions in the Installing Apache section the Apache config file should be the following file: /usr/conf/httpd.conf
Obviously the location of this file may be different if you installed Apache in a different location or if you installed it using a different method.

Firstly, we need to configure Apache to load the mod_mono module. To do this we need to edit the Apache config file, /usr/conf/httpd.conf, and add the following line to the end:

LoadModule mono_module /usr/modules/mod_mono.so

The above line tells Apache to load the module located at /usr/modules/mod_mono.so as the mono module.

The next thing that we need to do it configure Apache to serve some ASP.NET content. We will use the same ASP.NET Examples that we used with the XSP server above. To do this we need to tell Apache to serve content from the /usr/share/doc/xsp/test/ directory for a given path, lets say, /AspNetOnApache. This means that when you browse to http://localhost/AspNetOnApache you will be served the ASP.NET content in the /usr/share/doc/xsp/test/ directory.

Here are the additions you need to make to the Apache config file:

Alias /AspNetOnApache "/usr/share/doc/xsp/test"
MonoApplications "/AspNetOnApache:/usr/share/doc/xsp/test"

Finally, we need to tell Apache which module to use as the handler for requests. For Apache 1.3.x you can use:

<Directory /usr/share/doc/xsp/test>
    SetHandler mono
    <IfModule mod_dir.c>
        DirectoryIndex index.aspx
    </IfModule>
</Directory>

and for Apache 2.0.x you can use the above text OR you can use the following

<Location /AspNetOnApache>
    SetHandler mono
</Location>

Finally! We are there. Simply go to the console and type the command httpd to start Apache. Point your browser to http://localhost/AspNetOnApache and you should see a page similar to the one shown in Figure 3.

Apache web server on Linux showing ASP.NET examples pages.
Figure 3: Apache web server on Linux showing ASP.NET examples pages.

Some Examples

So after all that you should be able to serve ASP.NET content from at least one server on Linux. Just to help round off the “experience” I’ve decided to add a basic web application example to this article.

A simple web application example

Our simple web application is very simple indeed. It consists of a single page that displays some basic information about the machine that the page is hosted on and also some basic information about the request for the page. There are two files, index.aspx and index.aspx.cs, the former being the web page and the latter being the codebehind file for that page. So open up your favourite text editor or IDE and create the two files (hint: copy and paste is probably the quickest way):

index.aspx

<%@ Page language="c#" src="introtomono2/index.aspx.cs" 
         Inherits="SimpleWebApp.SimplePage" AutoEventWireup="false"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
   <HEAD>
      <title>Simple Page</title>
   </HEAD>
   <body>
      <form method="post" runat="server">
         <table width="450px" border="1px">
            <tr>
               <td colspan="2"><strong>Server Details</strong></td>
            </tr>
            <tr>
               <td>Server Name:</td>
               <td>
                  <asp:Label id="serverName" runat="server"></asp:Label></td>
            </tr>
            <tr>
               <td>Operating System:</td>
               <td>
                  <asp:Label id="operatingSystem" runat="server"></asp:Label>
               </td>
            </tr>
            <tr>
               <td>Operating System Version:</td>
               <td>
                  <asp:Label id="operatingSystemVersion" runat="server"><BR>                  </asp:Label>
               </td>
            </tr>
         </table>
         <br>
         <table width="450px" border="1px">
            <tr>
               <td colspan="2"><strong>Request Details</strong></td>
            </tr>
            <tr>
               <td>Page Requested:</td>
               <td>
                  <asp:Label id="requestedPage" runat="server"></asp:Label>
               </td>
            </tr>
            <tr>
               <td>Request From:</td>
               <td>
                  <asp:Label id="requestIP" runat="server"></asp:Label>
               </td>
            </tr>
            <tr>
               <td>User Agent:</td>
               <td>
                  <asp:Label id="requestUA" runat="server"></asp:Label>
               </td>
            </tr>
         </table>
      </form>
   </body>
</HTML>

index.aspx.cs

using System;
using System.Web.UI.WebControls;

namespace SimpleWebApp
{
   public class SimplePage : System.Web.UI.Page
   {
      protected Label operatingSystem;
      protected Label operatingSystemVersion;
      protected Label requestedPage;
      protected Label requestIP;
      protected Label requestUA;
      protected Label serverName;
   
      protected override void OnLoad(EventArgs e)
      {
         DisplayServerDetails();
         DisplayRequestDetails();

         base.OnLoad (e);
      }

      private void DisplayServerDetails()
      {
        serverName.Text = Environment.MachineName;
        operatingSystem.Text = Environment.OSVersion.Platform.ToString();
        operatingSystemVersion.Text = Environment.OSVersion.Version.ToString();
      }

      private void DisplayRequestDetails()
      {
         requestedPage.Text = Request.Url.AbsolutePath;
         requestIP.Text = Request.UserHostAddress;
         requestUA.Text = Request.UserAgent;
      }
   }
}

Once you have saved these two files we now need to be able to serve it. I saved the files to /home/bdelahunty/mono/webappexample/ and we now need to configure both XSP and Apache to serve pages from this location. As this is a simple web application example lets call it SimpleWebApp.

To get XSP to serve the page use the following command at the console (replacing /home/bdelahunty/mono/webappexample/ with the directory where you saved the files):

xsp --applications /SimpleWebApp:/home/bdelahunty/mono/webappexample/

To get Apache to serve the page simply add the following to the end of the Apache config file, /usr/conf/httpd.conf in my case (replacing /home/bdelahunty/mono/webappexample/ with the directory where you saved the files):

Alias /SimpleWebApp "/home/bdelahunty/mono/webappexample"
MonoApplications "/SimpleWebApp:/home/bdelahunty/mono/webappexample"   

You also need to add the following if you are using Apache 1.3.x:

<Directory /home/bdelahunty/mono/webappexample>
    SetHandler mono
        <IfModule mod_dir.c>
            DirectoryIndex index.aspx
        </IfModule>
</Directory>

and for Apache 2.0.x you can use the above text OR you can use the following:

<Location /SimpleWebApp>
    SetHandler mono
</Location>

Now just fire up your browser and point it to http://localhost/SimpleWebApp for Apache or http://localhost:8080/SimpleWebApp for XSP and you should see a page similar to the one shown in Figure 4.

The SimplePage.aspx file displaying the server and request             details.
Figure 4: The SimplePage.aspx file displaying the server and request details.

Problems with the Visual Studio .NET and IIS way?

If you are used to developing ASP.NET web applications with Visual Studio .NET then there are a few things you need to watch out for. When creating aspx pages Visual Studio .NET used the CodeBehind attribute in the pages @Page directive. However, CodeBehind is not actually an official ASP.NET @Page directive attribute and is only used by the IDE at design time and when compiling the ASP.NET application to a dll. You would normally then drop this compiled dll into the bin directory of your web application and IIS would automatically pick up the changes. This doesn’t work with XSP or mod_mono; you can’t just drop in a new pre-compiled dll and have the web server start using it.

You may or may not have noticed that I used the Src attribute in the @Page directive in the simple example above and I did not give any details about pre-compiling the web application to a dll that has to be deployed. I just pointed XSP and Apache to the directory where the index.aspx and index.aspx.cs files where located and the web servers handled the compilation of the web application the first time the page was called. This is one way you can get around the pseudo problem of not being able to just drop in a new pre-compiled dll. You can just drop in a new .cs codebehind file and the web server will compile it on the fly. This method does however require that you have all your codebehind files on the server. If you setup your permissions correctly then this is not an issue, if you don’t, it’s a big issue as any visitor to your site could potentially view the code behind your site and potentially come up with ways to hack it.

If you are used to the Visual Studio .NET and IIS way, or if you simply use Visual Studio .NET to build your web applications and want to just drop the pre-compiled dll into the bin directory then you can quickly overcome the problem by deploying your new dll and then restarting the web server. Use httpd -k restart to restart Apache after you have put in a new dll and if you are using XSP just shut it down and then restart XSP it.

Original Post: http://www.mono-project.com/docs/web/aspnet/

Mono has an implementation of ASP.NET 2.0, ASP.NET MVC and ASP.NET AJAX.

Quick Resources:

Mono’s ASP.NET implementations supports two kinds of applications:

  • Web Forms (Web Applications infrastructure).
  • Web Services (the SOAP-based RPC system).

Status and tests for ASP.NET 2.0 are available in our ASPTests page.

Running ASP.NET applications

To run your ASP.NET applications with Mono, you have three classes of options:

  • Apache hosting: use mod_mono, a module that allows Apache to serve ASP.NET applications.
  • FastCGI hosting: use the FastCGI hosting if you have a web server that supports the FastCGI protocol (for example Nginx) for extending the server. You also may use a web server that only has support for CGI using cgi-fcgi.
  • XSP: this is a simple way to get started, a lightweight and simple webserver written in C#.

For deploying applications, we recommend the use of the mod_mono or FastCGI approaches, as that will give you all the configuration options and flexibility that come with using Apache or a FastCGI server.

For quickly getting started, get familiar with Mono and ASP.NET, XSP is the ideal solution. Keep in mind that XSP is a very limited server and is only useful to get acquainted with ASP.NET and Mono, it only support HTTP 1.0 and does not provide much extensibility or configuration.

More advaned users can use the HttpListener and the ASP.NET hosting to create their own hosts for ASP.NET applications.

ASP.NET hosting with Apache

The mod_mono Apache module is used to run ASP.NET applications within the Apache web server.

The mod_mono module runs within an Apache process and passes all the requests to ASP.NET applications to an external Mono process that actually hosts your ASP.NET applications. The external ASP.NET host is called “mod-mono-server” and is part of the XSP module.

To use this, you must download and install the mod_mono and xsp components of Mono. mod_mono contains the actual Apache module, and xsp contains the actual ASP.NET hosting engine, both are available from our download page.

See the mod_mono page for details on installation and configuration.

ASP.NET hosting with Nginx

Nginx is a high-performance HTTP server which support running ASP.NET and ASP.NET MVC web applications through FastCGI protocol. See the FastCGI Nginx page for details on installation and configuration.

ASP.NET hosting with XSP

XSP is a standalone web server written in C# that can be used to run your ASP.NET applications with minimal effort. XSP works under both the Mono and Microsoft runtimes. The code is available from our download page (look for XSP web server) or from the git repository (module name: xsp).

The easiest way to start XSP is to run it from within the root directory of your application. It will serve requests on port 8080. Place additional assemblies in the bin directory. Other XSP options can be set on the command line, such as the application directory and the port to listen on.

XSP comes with a set of pages, controls and web services that you can use to test the server and see what ASP.NET looks like.

For example, once you install XSP, you can try some samples like this:

 $ cd /usr/lib/xsp/test
 $ xsp
 Listening on port: 8080
 Listening on address: 0.0.0.0
 Root directory: /home/cvs/mcs/class/corlib/Microsoft.Win32
 Hit Return to stop the server.

You can now browse to http://localhost:8080 and see various sample programs

SSL support in XSP

XSP supports SSL and TLS Client Certificates. For further details about setting it up, see the UsingClientCertificatesWithXSP document.

Configuration

Applications can be configured through the web.config file, the full documentation is available from MSDN, and also a Mono-specific version is available on this site here.

Additionally, you can configure Mono-specific ASP.NET settings (to have applications that behave differently depending on the operating system they are deployed in) using the ASP.NET Settings Mapping engine.

Other extensions

Check out ASP.NET Modules for details on how to support deflate/gzip encodings and authentication.

Debugging

By default xsp and xsp2 run in Release mode, which means that debugging line-number information will not be available in stack traces when errors occur.

To obtain line numbers in stack traces you need to do two things:

  1. Enable Debug code generation in your page. 2. Run Mono with the –debug command line option.

You must enable debug code generation in your page using the Debug=”true” in the top of your page, or setting the compilation flag in Web.config (compilation option).

Use the –debug command line option to Mono, this is done by setting the MONO_OPTIONS environment variable, like this:

$ MONO_OPTIONS=--debug xsp2
Listening on port: 8080 (non-secure)
Listening on address: 0.0.0.0
Root directory: /tmp/us
Hit Return to stop the server.

To do the same with the Apache mod_mono module, use the MonoDebug true directive in your apache configuration file.

Supported Versions

Mono supports ASP.NET 2.0, ASP.NET AJAX and a handful of 3.5 controls.

Limitations

Mono’s ASP.NET does not implement the following features:

  • Precompiled updatable web sites.
  • WebParts APIs.

Work in Progress

git access

Users interested in the latest version of mod_mono and xsp can retrieve these from our public git repository. The module names are mod_mono and xsp respectively. You will also need to check out the mcs module as the System.Web classes are in mcs/class/System.Web.

Designer

There is work in progress on an ASP.NET Designer the designer will eventually be integrated into the MonoDevelop IDE.

Install Mono on Linux

http://www.mono-project.com/docs/getting-started/install/linux/#centos-fedora-and-derivatives

The Linux community has made Mono available for various distributions, check the download page for a list of packages.

Regardless of your distribution, you will need the Mono Project GPG signing key, which package managers require.

Debian, Ubuntu, and derivatives

Add the Mono Project GPG signing key in a root shell with:

apt-key adv --keyserver pgp.mit.edu --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF

Next, add the package repository in a root shell:

echo "deb http://download.mono-project.com/repo/debian wheezy main" > /etc/apt/sources.list.d/mono-xamarin.list

Update your package cache if necessary (i.e. run apt-get update), and run a package upgrade to upgrade existing packages to the latest available. Then install Mono as described in the usage section.

Note: While the APT package is built against Debian Wheezy, it is compatible with a number of Debian derivatives (including Ubuntu) which means you can use the same repository across all these distributions.

Ubuntu 12.04 and 12.10

To enable installation on Ubuntu 12.04 and Ubuntu 12.10 (and their derivatives), you will need to add a second repository to your system, in addition to the generic Debian/Ubuntu repository above:

echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" >> /etc/apt/sources.list.d/mono-xamarin.list

mod_mono on Ubuntu 13.10 and later, Debian 8.0 and later

To enable mod_mono installation on Ubuntu 13.10 and later, and Debian 8.0 and later (and their derivatives), you will need to add a second repository to your system, in addition to the generic Debian/Ubuntu repository above:

echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" >> /etc/apt/sources.list.d/mono-xamarin.list

CentOS, Fedora, and derivatives

Add the Mono Project GPG signing key in a root shell with:

rpm --import "https://pgp.mit.edu/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF"

Next, add the package repository in a root shell:

yum-config-manager --add-repo http://download.mono-project.com/repo/centos/

Update your package cache if necessary, and run a package upgrade to upgrade existing packages to the latest available.

Users of CentOS or RHEL (or similar distributions) may need to add the EPEL repository to their system to satisfy all dependencies

Usage

The package mono-devel should be installed to compile code.

The package mono-complete should be installed to install everything – this should cover most cases of “assembly not found” errors.

Notes

After the installation completed successfully, it’s a good idea to run through the basic hello world examples on this page to verify Mono is working correctly.

Note: Mono on Linux by default doesn’t trust any SSL certificates so you’ll get errors when accessing HTTPS resources. To import Mozilla’s list of trusted certificates and fix those errors, you need to run mozroots --import --sync.

Testing is mono installed successfully

Mono Basics

After you get Mono installed, it’s probably a good idea to run a quick Hello World program to make sure everything is set up properly. That way you’ll know that your Mono is working before you try writing or running a more complex application.

Console Hello World#

To test the most basic functionality available, copy the following code into a file called hello.cs.

using System;
 
public class HelloWorld
{
    static public void Main ()
    {
        Console.WriteLine ("Hello Mono World");
    }
}

To compile, use mcs:

mcs hello.cs

The compiler will create “hello.exe”, which you can run using:

mono hello.exe

The program should run and output:

Hello Mono World

Winforms Hello World#

The following program tests writing a Winforms application.

using System;
using System.Windows.Forms;

public class HelloWorld : Form
{
    static public void Main ()
    {
        Application.Run (new HelloWorld ());
    }

    public HelloWorld ()
    {
        Text = "Hello Mono World";
    }
}

To compile, use mcs with the -pkg option to tell the compiler to pull in the Winforms libraries:

mcs hello.cs -pkg:dotnet

The compiler will create “hello.exe”, which you can run using:

mono hello.exe

NOTE: on Mac OS X you’ll have to wait around a minute the very first time you run this command.

ASP.Net Hello World#

Create a text file with the name hello.aspx and the content:

<%@ Page Language="C#" %>
<html>
<head>
   <title>Sample Calendar</title>
</head>
<asp:calendar showtitle="true" runat="server">
</asp:calendar>

Then run the xsp4 command from that directory:

xsp4

Use a web browser to contact http://localhost:9000/hello.aspx

Gtk# Hello World#

The following program tests writing a Gtk# application.

using Gtk;
using System;

class Hello
{
    static void Main ()
    {
        Application.Init ();

        Window window = new Window ("Hello Mono World");
        window.Show ();

        Application.Run ();
    }
}

To compile, use mcs with the -pkg option to tell the compiler to pull in the Gtk# libraries (note that Gtk# must be installed on your system for this to work):

mcs hello.cs -pkg:gtk-sharp-2.0

The compiler will create “hello.exe”, which you can run using:

mono hello.exe

mod_mono

mod_mono is an Apache 2.0/2.2/2.4.3 module that provides ASP.NET support for the web’s favorite server, Apache.

The module passes off requests for ASP.NET pages to an external program, mod-mono-server, which actually handles the requests. The communication between the Apache module and mod-mono-server is established using a Unix socket or a TCP socket.

The most simple scenario uses Apache as the HTTP server front end which passes the requests to mod-mono-server to handle, the following diagram illustrates how this setup works:

Modmono-basic-setup.PNG

Mod_mono is an Apache module that is hosted inside Apache. Depending on your configuration the Apache box could be one or a dozen of separate processes, all of these process will send their ASP.NET requests to the mod-mono-server process. The mod-mono-server process in turn can host multiple independent applications. It does this by using Application Domains to isolate the applications from each other, while using a single Mono virtual machine.

Although AppDomains provide an adequate level of isolation, mod_mono can also be configured to route different urls to different mod-mono-server processes. You can use this to:

  • As an ISP, isolate different customers to different processes
  • Allow experimental code to run in one server, independent of production code.
  • Allow the kernel to enforce different isolation rules for different processes (for example with AppArmor or SELinux)
  • Setup different CPU, Disk and memory quotas to different processes

Modmono-multiple-servers.PNG

For example, in the setup above, the various Apache workers will route requests to /forums and /support to a mod-mono-server that is used by the “community” user on the server. This mod-mono-server will still use two separate AppDomains to isolate the forums software from the support software.

The /blog url will be sent to the mod-mono-server that is ran by the marketing group, the /api url will be sent to the mod-mono-server for user engineering while the application in /testing will be handled by an experimental version of Mono.

Requirements

You will need apache , the web server, installed.

From Downloads you will need mono, xsp and mod_mono.

Distribution-Specific Documentation

If you are using one of these linux distributions, you should look at the corresponding documentation before reading the rest of this page, as some things are different on every distro. It is also always recommended to use your distribution’s official packages when available, rather than compiling from source.

Easy Configuration of Mod_Mono

When you installed XSP, a bunch of sample ASP.NET pages and web services were installed too. If the prefix used to configure XSP was /usr, the sample files are located in /usr/lib/xsp/test.

If your needs are not very complicated, all you need is to use AutoHosting, this basically means that you load the mod_mono.conf file, like this in your Apache configuration file:

Include /etc/apache2/mod_mono.conf

And applications will start to be served. To try it out, copy the /usr/lib/xsp/test directory to your Apache home (in openSUSE this is /srv/www/hdtocs).

It is recommended that you create a directory per application that you want served. This will allow you to xcopy deploy your applications from Windows to Linux if you want to.

More on automatic configuration of mod_mono applications is in AutoHosting.

mod_mono.conf loads the mod_mono module, associates ASP.NET file extensions with the ASP.NET MIME type and adds index.aspx, Default.aspx, and default.aspx as automatic directory index pages (with the DirectoryIndex directive). If you don’t include mod_mono.conf in your main Apache configuration, you will at least need to have the mod_mono.so module loaded with:

LoadModule mono_module /usr/lib/httpd/modules/mod_mono.so

For more detailed configuration and manual tuning keep reading.

mod_mono will automatically launch mod-mono-server and start the web application on the first request for a page handled by mod_mono. In the early days of mod_mono, you had to start mod-mono-server by yourself, ensuring that it had all the parameters needed to understand the requests forwarded by the module. This is still an option for those who want mod-mono-server to have a separate life cycle from apache, but you will probably prefer to use mod_mono built-in ability to start and stop mod-mono-server for you.

Apache performance tweaks

You might want to consider modifying the apache configuration so that mod_mono performs better.

Keep alive

The HTTP/1.1 protocol defines a theoretically performance-improving mechanism – keep alive. What it means is that the web server can keep the connection open for a while for the client to request several resources over the same connection. In reality, however, very often that feature becomes a performance killer. The reason is that each keep alive session requires the server to keep the process (or thread) busy in order for the timeout to happen or for the client to close the connection. Apache contains configuration directives to set the number of maximum clients serviced, the number of threads/processes (servers) to spawn etc (for more information see http://httpd.apache.org/docs/2.2/). Each time a keep alive session is open and the client does not use it, Apache will still keep the server process/thread busy and thus it won’t be able to accept another connection on that server – which will limit the throughput. There are two solutions to this problem. The better one, in my opinion, is to turn keep alive off completely by putting this directive somewhere in your Apache config:

KeepAlive Off

If, however, you want to use keep alive, you might try decreasing the session timeout to a small value (for instance 2 seconds) by putting this directive in the Apache configuration:

KeepAliveTimeout 2

MPM worker

Apache 2.x comes with several processing modules (that is – servers, so-called MPMs for Multi Processing Module) implementing different server models. The one installed by default by most distributions is the prefork MPM which implements the traditional, one OS process per server, model and is the same what in the earlier Apache versions. Another module usually available with your distribution is the worker MPM. That module implements a mixed process/thread model which spawns several processes as well, but each of them can create a configurable number of service threads. It is advisable to use the worker MPM with mod_mono. Unfortunately, PHP seems to not necessarily work with the worker MPM, so you may not be able to go this route.

Configuring Mod_Mono

When AutoHosting does not fit your needs, you will need to include several mod_mono Apache directives in your main Apache configuration file (often /etc/httpd/conf/httpd.conf, or the like in /etc/apache2) to get the site running.

Mod_Mono Configuration Tool

The Apache mod_mono configuration tool can generate a configuration for name-based Virtual Hosts (i.e., how this site is configured to traffic to mono-project.com, http://www.mono-project.com, etc), and configurations for ASP.NET Applications (what IIS traditionally referred to as a Virtual Directory), such as the mod_mono configuration application served at http://go-mono.com/config-mod-mono/

In the simplest case, you shouldn’t have to supply the tool with anything more than a server or application name; the tool will suggest a path where you can deploy your application. With the intention of making developing and porting applications as painless as possible, the default configuration will set mod_mono to run with both mono debugging and platform abstraction enabled. These may not be the best options for production web sites, so consider disabling those features if/when you no longer need them.

Once you’ve completed the form, the tool will generate a configuration you can save to disk (/etc/apache2/conf.d/ on SUSE/openSUSE). To begin serving your newly configured application, simply restart apache:

        sudo /sbin/service apache2 restart

Manual Mod_Mono Configuration

The following assumes you have included mod_mono.conf in your main configuration file as described above. Further, it is important (as of Mono 1.2.5) to place the remaining mod_mono directives after the User and Group directives. They can just go at the end, or inside VirtualHost sections.

A basic setup is as follows (with line numbers added for convenience):

1   MonoAutoApplication disabled
2   AddHandler mono .aspx .ascx .asax .ashx .config .cs .asmx .axd
3   MonoApplications "/:/home/username/www"

The first line disables the AutoHosting feature. (If inside a VirtualHost section, it disables it just for that virtual host).

The second line instructs Apache that processing of files with .aspx, etc. extensions should be delegated to mod_mono (rather than Apache processing them itself as plain-text files).

The third line instructs mod_mono that an ASP.NET application exists at the root directory of the web site (i.e. at http://www.example.com/), and that this virtual path corresponds to the physical path on disk of /home/username/www. Normally, the physical path will match whatever Apache would map the given virtual path to. So if the virtual path is /, as in this example, the physical path matches what is in the DocumentRoot directive for Apache. This is important because in that virtual path, Apache itself will continue to serve images, static HTML, and other files, based on the physical path it knows in DocumentRoot, while mod_mono will handle files with .aspx, etc. extensions (or whatever was specified in AddHandler) based on the physical path provided in the MonoApplications directive.

Here is another configuration that sets up the ASP.NET test suite that comes with mod_mono.

Let’s say you want those file to be available under the virtual path /test. Edit your httpd.conf file (hint: /etc/httpd, /etc/apache2) and append the following lines (remove the numbers ;-):

1   Alias /test "/usr/share/doc/xsp/test"
2   MonoApplications "/test:/usr/share/doc/xsp/test"
3   <Location /test>
4       SetHandler mono
5   </Location>

Unlike the first example, this example assumes that the virtual path “/test” does not already correspond to the physical path /usr/share/doc/xsp/test. The Alias directive is a standard Apache directive to map a virtual path to a physical path. The second line creates an ASP.NET application in something other than the root virtual path. Lines 3-5 instruct Apache that absolutely all files in the /test virtual path are to be handled by mod_mono. (mod_mono can handle non-ASP.NET pages as well. It will just send other files to the client directly without special processing.)

Now start/restart Apache and browse http://hostname/test/index.aspx (where hostname is the name of the server, or 127.0.0.1 if you’re running Apache locally). If you cannot see the test page, go to the troubleshooting section. Otherwise, welcome to ASP.NET!

Okay, it worked. But, what happened? When you started apache, mod_mono launched mod-mono-server. Later, when you requested any page under /test, mod_mono connected to mod-mono-server, forwarded the request data and retrieved the response that is sent to your browser. Finally, if you stop apache, mod_mono will tell mod-mono-server to die.

It is possible to put these directives inside a VirtualHost section as well.

If your site uses .NET 2.0 classes, you will need to instruct mod_mono to spawn the .NET 2.0 version of mod-mono-server, instead of the default .NET 1.1 version. To do that, use the following, changing the path to mod-mono-server2 as needed:

MonoServerPath /usr/bin/mod-mono-server2

If you use AddHandler you might want to let mod-mono-server know about your DirectoryIndex directive by doing something like this in your web.config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="MonoServerDefaultIndexFiles" value="mywierdindexfile.html,index.aspx" />
</appSettings>
</configuration>

More on Applications

How do you go about making mod_mono handle several applications? Let’s try the easiest option. You will need this in your httpd.conf:

1   Alias /test "/usr/share/doc/xsp/test"
2   Alias /personal "/home/user/mypages"
3   AddMonoApplications default "/test:/usr/share/doc/xsp/test,/personal:/home/user/mypages"
4   <Location /test>
5       SetHandler mono
6   </Location>
7   <Location /personal>
8       SetHandler mono
9  </Location>

The significant change is in line 4:

AddMonoApplications "/test:/usr/share/doc/xsp/test,/personal:/home/user/mypages"

    ...is equivalent to...

AddMonoApplications "/test:/usr/share/doc/xsp/test"
AddMonoApplications "/personal:/home/user/mypages"

This way you can keep all the configuration related to an application in a separate file (Alias, AddMonoApplications, Location,…).

If you serve mod_mono applications in multiple virtual hosts, you can use this syntax:

AddMonoApplications "www.example.com:/:/home/exampledotcom/www"
AddMonoApplications "www.sample.com:/:/home/sampledotcom/www"

The above example instructs mod-mono-server to create two applications, one mapping http://www.example.com/ to /home/exampledotcom/www and the other mapping http://www.sample.com/ to /home/sampledotcom/www.

Multiple Applications, Multiple mod-mono-servers

You might want to run different applications in different instances of mod-mono-server. There are a number of reasons for doing this:

  • If you want to run a production and testing environments.
  • You need completely separate Mono instances running.
  • If you don’t want Session or Application level objects to be shared among applications or that you want to set certain memory or CPU usage restrictions for an application.

Let’s see the configuration needed to achieve this separation for the two applications in the previous example. (Alias directives are omitted for brevity, and this example assumes the AddHandler directive has been used to associate ASP.NET file extensions with mod_mono.)

1   MonoApplications testing "/test:/usr/share/doc/xsp/test"
2   <Location /test>
3      MonoSetServerAlias testing
4   </Location>
5
6   MonoApplications personal "/personal:/home/user/mypages"
7   <Location /personal>
8      MonoSetServerAlias personal
9   </Location>

When (Add)MonoApplications is given two arguments, the first argument is understood as a name or alias for a particular instance of the mod-mono-server backend. With this configuration mod_mono will start two instances of mod-mono-server whose aliases are ‘testing’ and ‘personal’. The ‘testing’ instance will handle /test and the ‘personal’ instance will handle /personal.

MonoSetServerAlias tells mod_mono which instance of mod-mono-server will be used to process the requests for this <Location>. It can be used with apache <Directory> too.

The alias used when no alias is provided, as in the earlier examples, is “default”. All of the mod_mono directives below that show an alias as the first argument also can be specified by leaving the alias out, in which case the “default” alias is used.

Control panel

mod_mono provides a simple web-based control panel for restarting the mod-mono-server, which is useful when assemblies need to be reloaded from disk after they have been changed. To activate the control panel, place the following in your httpd.conf:

<Location /mono>
  SetHandler mono-ctrl
  Order deny,allow
  Deny from all
  Allow from 127.0.0.1
</Location>

The Order/Deny/Allow access controls above restrict access to the control panel to the computer with IP address 127.0.0.1. Replace this (or add more Allow lines) with the IP address of your own computer so that you can access the control panel. Note that anyone on the machine 127.0.0.1 will have the ability to affect any configured mod_mono applications. (These directives placed in a VirtualHost section allow access to only mod_mono applications configured within that virtual host.)

The control panel is then accessible at http://yourdomain.com/mono. It allows you to:

  • Restart mod-mono-server backends for all or individual applications.
  • Stop or resume handling pages for all or individual applications.
  • See how many concurrent requests are currently being processed.
  • See how many requests are waiting to be processed, according to the MonoMaxActiveRequests directive (explained below).
  • See how many requests have been served since the last restart if the MonoAutoRestartMode Requests directive is used (explained below).
  • See how much time has elapsed since the last restart if the MonoAutoRestartMode Time directive is used (explained below).

Advanced options

Automatic restart of the mod-mono-server backend

mod_mono can automatically restart the Mono (mod-mono-server) backend that is handling requests after a certain amount of time. This is useful if you find that the mono process is growing indefinitely over time, or if you just need to make sure you clean house every so often.

There are two automatic restart methods: one based on time, and one based on the number of requests served. You can active them as follows:

# Auto-restart after three hours.
1 MonoAutoRestartMode Time
2 MonoAutoRestartTime 00:03

The time format above is DD[:HH[:MM[:SS]]].

# Auto-restart after 10,000 requests served.
1 MonoAutoRestartMode Requests
2 MonoAutoRestartRequests 10000

As with most other mod_mono directives, the first parameter to a directive can be the name or alias of a mod-mono-server. This is always optional and is omitted in the examples above.

Limiting the number of concurrent requests

The number of concurrent requests that can be processed by the mod-mono-server backend is limited by the size of the ThreadPool, and you could experience deadlocks when too many requests are going at once. As a result of the deadlocks, Apache child process instances that are processing requests get backed up until no more incoming HTTP connections can be made (even for any virtual host).

mod_mono will limit the number of concurrent requests that are passed off to mod-mono-server, and when the limit is reached, incoming requests wait for a certain amount of time until more requests can be passed off to the backend. The default limit of concurrent requests is 20, and the default limit of requests waiting to be passed off to the backend is 20. This should be just below the amount mod-mono-server can process without reaching the ThreadPool limit on a single processor machine.

To adjust the limits, use these directives:

1 MonoMaxActiveRequests 20
1 MonoMaxWaitingRequests 20

A value of zero disables the limits.

To adjust the number of threads in the threadpool, you have two choices: this can be either configured as part of your ASP.NET application configuration or it can be made global to Mono. you can do this by using the MONO_THREADS_PER_CPU environment variable, the default being 50 (25 on windows):

export MONO_THREADS_PER_CPU=2000

If you are using Mono from Apache to run ASP.NET, you can use the MonoSetEnv configuration option in Apache:

MonoSetEnv MONO_THREADS_PER_CPU=2000

For ASP.NET applications it’s also a good idea to tweak the default values found in machine.config, inside <system.web> section:

    <httpRuntime executionTimeout="90"
           maxRequestLength="4096"
           useFullyQualifiedRedirectUrl="false"
               minFreeThreads="8"
           minLocalRequestFreeThreads="4"
           appRequestQueueLimit="100" />

Setting hard memory and time limits

Here’s an example on how to set memory and CPU limits for a given server:

1   LoadModule mono_module modules/mod_mono.so
2   Alias /jeanette "/home/jeanette/web"
3   AddMonoApplications jeanette "/jeanette:/home/jeanette/web"
4   MonoMaxMemory jeanette 200000000
5   MonoMaxCPUTime jeanette 3600
6   <Location /jeanette>
7       MonoSetServerAlias jeanette
8       SetHandler mono
9   </Location>

Lines 4 and 5 set the maximum memory to be used (bytes) and the maximum CPU time consumed (seconds) by the ‘jeanette’ mod-mono-server instance. After reaching the limit, the OS will kill mod-mono-server. A new instance should start automatically on the next request. (But, JT notes that these directives don’t work at all for him.)

Unix and TCP sockets

We said that mod_mono and mod-mono-server can use a unix or a TCP socket to sent data back and forth. Use of unix sockets is the default, but you can use a TCP socket in case you have several computers running apache and one single machine providing mod-mono-server services.

The only parameter that you can control when using a unix socket is the file name. The directive is MonoUnixSocket:

    LoadModule mono_module modules/mod_mono.so

    Alias /julia "/home/julia/web"
    AddMonoApplications default "/julia:/home/julia/web"
    # When no MonoUnixSocket is provided, the default
    # is /tmp/mod_mono_server[_alias]
    # In this case, for the 'default' alias: /tmp/mod_mono_server
    <Location /julia>
        SetHandler mono
    </Location>

    Alias /jennie "/home/jennie/web"
    AddMonoApplications jennie "/jennie:/home/jennie/web"
    # In this case, alias 'jennie': /tmp/mod_mono_server_jennie
    <Location /jennie>
        MonoSetServerAlias jennie
        SetHandler mono
    </Location>

    Alias /juno "/home/juno/web"
    AddMonoApplications juno "/juno:/home/juno/web"
    # Uses a file under juno's home directory
-   MonoUnixSocket juno /home/juno/tmp/juno_server
    <Location /juno>
        MonoSetServerAlias juno
        SetHandler mono
    </Location>

You can set the file name to whatever you want as long as the user running apache has the necessary permissions to create and remove that file.

In order to run an instance of mod-mono-server that listens on a TCP socket, there’s a mandatory MonoListenPortdirective and an optional MonoListenAddress. See them in action:

    LoadModule mono_module modules/mod_mono.so

    Alias /jazmin "/home/jazmin/web"
    AddMonoApplications jazmin "/jazmin:/home/jazmin/web"
    # 'jazmin' mod-mono-server will be listening on
    # port 9000, address 127.0.0.1
-   MonoListenPort jazmin 9000
    <Location /jazmin>
        MonoSetServerAlias jazmin
        SetHandler mono
    </Location>

    Alias /joan "/home/joan/web"
    AddMonoApplications joan "/joan:/home/joan/web"
    # 'joan' mod-mono-server will be listening on
    # port 7000, any address (0.0.0.0)
-   MonoListenPort joan 7000
-   MonoListenAddress joan 0.0.0.0
    <Location /joan>
        MonoSetServerAlias joan
        SetHandler mono
    </Location>

MonoUnixSocket and MonoListenPort are mutually exclusive. Don’t use both.

Paths

In case it is needed, you can provide alternative locations for mod-mono-server. Other directories containing assemblies that mono could not find in the default search paths can also be specified. Mono needs a writable directory used by the windows I/O emulation layer that is usually in the user’s home .wapi directory ($HOME/.wapi). In mod_mono, the directory where .wapi is created is set to /tmp, but you can change that too.

    LoadModule mono_module modules/mod_mono.so

    Alias /jane "/home/jane/web"
    AddMonoApplications jane "/jane:/home/jane/web"

    MonoServerPath jane /nfs/mono-1.1.17/mod-mono-server

    <Location /jane>
        MonoSetServerAlias jane
        SetHandler mono
    </Location>

    Alias /jackie "/home/jackie/web"
    AddMonoApplications jackie "/jane:/home/jackie/web"

    # This uses mono from git and the ASP.NET 2.0 mod-mono-server
    MonoServerPath jackie /svn/install/bin/mod-mono-server2

    #
    # Add this directories to the default paths searched by mono
    # when looking for assemlies
    MonoPath jackie "/home/jackie/NET/assemblies:/usr/local/assemblies"
    # The .wapi directory will be created in /home/jackie
    MonoWapidir jackie "/home/jackie"
    <Location /jackie>
        MonoSetServerAlias jackie
        SetHandler mono
    </Location>

Troubleshooting

ASP.NET 2 applications do not work

If your site uses .NET 2.0 classes, you will need to instruct mod_mono to spawn the .NET 2.0 version of mod-mono-server, instead of the default .NET 1.1 version. To do that, use the following, changing the path to mod-mono-server2 and the alias as needed:

MonoServerPath default /usr/bin/mod-mono-server2

Access forbidden

If you’re getting a 403 response from apache that probably means that the user running apache does not have proper permissions to read the physical directory. Check the permissions on all the directories and the files and make then readable by the user running apache.

mod-mono-server does not start

Check the apache error_log file (/var/log/apache2/error_log …). It might contain some hints on what’s happening. Possible causes are that mono or mod-mono-server are not found in the path, that a file with the same name as the unix socket mod-mono-server tries to create already exists and mod-mono-server can’t remove it or a stale .wapi directory.

Restarting apache does not kill the spawned mod-mono-server.exe(s)

Use ‘apachectl reload’ instead of ‘apachectl restart’. There is some problem (may be fixed in apache 2.0.54) that made ‘restart’ not work properly.

For cookie-less sessions to work, you need to use SetHandler. AddHandler won’t work.

Under high load, mono process consumes a lot of memory, website stops responding

These symptoms have been reported, but their underlying causes are not known. Set the MonoAutoRestartMode, MonoAutoRestartRequests, MonoMaxActiveRequests, and MonoMaxWaitingRequests directives as described earlier to limit the lifetime of the mono process and to restrict the concurrency happening in the server.

mod_mono on Windows

For a Windows port of mod_mono, see here. This is a work in progress.

Profiling mod-mono-server

If you want to find the bottleneck in you ASP.NET application using mod_mono, and assuing you’re letting mod_mono start mod-mono-server, you’ll need to follow these steps:

  1. Start apache.
  2. Run ‘ps aux’ and copy the command line used to run mod-mono-server.exe
  3. Stop apache
  4. With the same user that runs apache, run the command line copied in 2 adding the ‘–profile’ parameter to mono.
  5. Start apache.
  6. Do a few requests (they will take a lot to process).
  7. Stop apache
  8. mod-mono-server will stop and you’ll get profile output.

Note that when –profile is enabled, mono is *extremely* slow. Do as many request as you need to get a result that excludes start up stuff.

Compiling mod_mono From Source

If you already have installed mod_mono as a package, skip this section.

Before compiling mod_mono, you need the development packages for apache installed (apache-dev…). You should have a file called mod_mono-X.Y.Z.tar.gz at this stage. Follow these steps:

    $ tar xzf mod_mono-X.Y.Z.tar.gz
    $ cd mod_mono-X.Y.Z
(1) $ ./configure
    $ make
(2) $ sudo make install

There are a few interesting options for (1) that you might want/need to use:

--prefix= /xxx/yyy
This will set the base path for installing mod_mono files.

--with-mono-prefix= /aaa/bbb
If the prefix for mod_mono is different from the one used for mono, you should set this to the prefix used for mono in order to make the default paths to mono executable and mod-mono-server.exe be correct. It is not mandatory, but useful.

--with-apxs= /xxx/yyy/apxs
If your system has different apache development files installed (ie, 1.3, 2.0 or 2.2) you might need this to choose the target version for mod_mono. Provide the full path to the apxs executable of the version that you want.

--with-apr-config= /xxx/yyy
If you get errors when compiling for apache 2 because some headers files are not found, use this option. It takes the full path to apache 2 apr-config tool.

--enable-debug
You will get more output in the apache error_log file. Useful when debugging.

Improving mod_mono

See our Improving mod_mono page for details on things that could be improved in the module.

mod_mono configuration examples

Introduction

mod_mono is an Apache 1.3/2.0 module that aims to provide ASP.NET support for the web’s favorite browser.

The module relays on an external program, mod-mono-server, to actually handle the requests. The communication between both is established using a unix socket or a TCP socket.

In the early days of mod_mono, you had to start mod-mono-server by yourself, ensuring that it had all the parameters needed to understand the requests forwarded by the module. This is still an option for those who want mod-mono-server to have a separate life cycle from apache, but you will probably prefer to use mod_mono built-in ability to start and stop mod-mono-server for you.

Requisites

You will need apache, the web server, installed.

From the Mono project ‘Downloads’ page you can get mono, XSP and mod_mono. XSP is the module where mod-mono-server resides.

Compiling mod_mono

If you already have installed mod_mono as a package, skip this section.

Before compiling mod_mono, you need the development packages for apache installed (apache-dev…). You should have a file called mod_mono-X.Y.Z.tar.gz at this stage. Follow these steps:

    $ tar xzf mod_mono-X.Y.Z.tar.gz
    $ cd mod_mono-X.Y.Z
(1) $ ./configure
    $ make
(2) $ make install

May be you need to run ‘su’ before (2).
There are a few interesting options for (1) that you might want/need to use:

  • –prefix=/xxx/yyy
    This will set the base path for installing mod_mono files.
  • –with-mono-prefix=/aaa/bbb
    If the prefix for mod_mono is different from the one used for mono, you should set this to the prefix used for mono in order to make the default paths to mono executable and mod-mono-server.exe be correct. It is not mandatory, but useful.
  • –with-apxs=/xxx/yyy/apxs
    If your system has different apache development files installed (ie, 1.3 and 2.0) you might need this to choose the target version for mod_mono. Provide the full path to the apxs executable of the version that you want.
  • –with-apr-config=/xxx/yyy
    If you get errors when compiling for apache 2 because some headers files are not found, use this option. It takes the full path to apache 2 apr-config tool.
  • –enable-debug
    You will get more output in the apache error_log file. Useful when debugging.

Configuration examples explained

Now that you have mono, XSP and mod_mono installed, you want some action.

Your first time

When you installed XSP, a bunch of sample ASP.NET pages and web services were installed too. If the prefix used to configure XSP was /usr, the sample files are located in /usr/share/doc/xsp/test.

Let’s say you want those file to be available under the virtual path /test. Edit your httpd.conf file (hint: /etc/httpd, /etc/apache2) and append the following lines (remove the numbers ;-):

1   LoadModule mono_module modules/mod_mono.so
2   Alias /test "/usr/share/doc/xsp/test"
3   AddMonoApplications default "/test:/usr/share/doc/xsp/test"
4   <Location /test>
5       SetHandler mono
6   </Location>

In line 1, you might need to use the full path to mod_mono.so.

Ok. Now start/restart apache and browse http://127.0.0.1/test/index.aspx. If you cannot see the test page, go to the troubleshooting section, otherwise, welcome to ASP.NET!

Now for the explanation of what the lines you added to httpd.conf do. Line 1 tells apache to load mod_mono module. I use line 2 always so that apache can check files and directories and appends a trailing slash if someone requests /test.

The first argument to AddMonoApplications in line 3 will be discussed in next section. The second one is passed to mod-mono-server so that it knows that the /test virtual path corresponds to the physical path /usr/share/doc/xsp/test. Then in line 5, inside our chosen location, we tell apache that mod_mono will handle all requests down /test/.

Okay, it worked. But, what happened? When you started apache, mod_mono launched mod-mono-server. Later, when you requested any page under /test, mod_mono connected to mod-mono-server, forwarded the request data and retrieved the response that is sent to your browser. Finally, if you stop apache, mod_mono will tell mod-mono-server to die.

More on applications

How do you go about making mod_mono handle several applications? Let’s try the easiest option. You will need this in your httpd.conf:

1   LoadModule mono_module modules/mod_mono.so
2   Alias /test "/usr/share/doc/xsp/test"
3   Alias /personal "/home/user/mypages"
4   AddMonoApplications default "/test:/usr/share/doc/xsp/test,/personal:/home/user/mypages"
5   <Location /test>
6       SetHandler mono
7   </Location>
8   <Location /personal>
9       SetHandler mono
10  </Location>

As you can see, it’s just a matter of adding the line 3 (like line 2) and lines 8, 9, 10 (similar to 5, 6, 7). The other change is in AddMonoApplications (4), whose value got the new application virtual and physical paths appended.

Now let’s focus on that line 4. Earlier in this document we said that mod_mono can run one or more instances of mod-mono-server and connects to it/them in order to dispatch ASP.NET requests. The first argument to AddMonoApplications and most of the other directives supported is an alias for a running mod-mono-server. Other directives allow omitting the first argument. In that case, ‘default’ is assumed. As you probably guessed:

AddMonoApplications default "/test:/usr/share/doc/xsp/test,/personal:/home/user/mypages"

	...is equivalent to...

AddMonoApplications default "/test:/usr/share/doc/xsp/test"
AddMonoApplications default "/personal:/home/user/mypages"

This way you can keep all the configuration related to an application in a separate file (Alias, AddMonoApplications, Location,…).

2 applications, 2 mod-mono-server

You might want to run different applications in different instances of mod-mono-server. The rationale for this can be that you don’t want Session or Application level objects to be shared among applications or that you want to set certain memory or CPU usage restrictions for an application or…

Let’s see the configuration needed to achieve this separation for the two applications in the previous example:

1   LoadModule mono_module modules/mod_mono.so
2   Alias /test "/usr/share/doc/xsp/test"
3   AddMonoApplications default "/test:/usr/share/doc/xsp/test"
4   <Location /test>
5       SetHandler mono
6   </Location>
7
8   Alias /personal "/home/user/mypages"
9   AddMonoApplications personal "/personal:/home/user/mypages"
11  <Location /personal>
12      MonoSetServerAlias personal
13      SetHandler mono
14  </Location>

With this configuration mod_mono will start two instances of mod-mono-server whose aliases are ‘default’ and ‘personal’. The ‘default’ instance will handle /test and the ‘personal’ instance will handle /personal. Every time mod_mono finds a new alias name in one of its directives, it will assign all the parameters for that alias to a new mod-mono-server instance.

As you can see there are two differences, apart from some lines shuffled. One is that AddMonoApplications in line 9 changed its first argument to be ‘personal’. The other is line 12, that introduces MonoSetServerAlias. This directive tells mod_mono which instance of mod-mono-server will be used to process the requests for this <Location>. It can be used with apache <Directory> too. Inside <Location /test> we didn’t need to use MonoSetServerAlias as the absence of this directive means that we want the ‘default’ instance to be used.

Setting limits

You know how to make mod_mono start one or more mod-mono-server instances. Here’s an example on how to set memory and CPU limits for a given server:

1   LoadModule mono_module modules/mod_mono.so
2   Alias /jeanette "/home/jeanette/web"
3   AddMonoApplications jeanette "/jeanette:/home/jeanette/web"
4   MonoMaxMemory jeanette 200000000
5   MonoMaxCPUTime jeanette 3600
6   <Location /jeanette>
7       MonoSetServerAlias jeanette
8       SetHandler mono
9   </Location>

Lines 4 and 5 set the maximum memory to be used (bytes) and the maximum CPU time consumed (seconds) by the ‘jeanette’ mod-mono-server instance. After reaching the limit, the OS will kill mod-mono-server. Upon next request mod-mono-server will be restarted by mod_mono with the same limits.

Unix and TCP sockets

We said that mod_mono and mod-mono-server can use a unix or a TCP socket to sent data back and forth. Use of unix sockets is the default, but you can use a TCP socket in case you have several computers running apache and one single machine providing mod-mono-server services.

The only parameter that you can control when using a unix socket is the file name. The directive is MonoUnixSocket:

    LoadModule mono_module modules/mod_mono.so

    Alias /julia "/home/julia/web"
    AddMonoApplications default "/julia:/home/julia/web"
    # When no MonoUnixSocket is provided, the default
    # is /tmp/mod_mono_server[_alias]
    # In this case, for the 'default' alias: /tmp/mod_mono_server
    <Location /julia>
        SetHandler mono
    </Location>

    Alias /jennie "/home/jennie/web"
    AddMonoApplications jennie "/jennie:/home/jennie/web"
    # In this case, alias 'jennie': /tmp/mod_mono_server_jennie
    <Location /jennie>
        MonoSetServerAlias jennie
        SetHandler mono
    </Location>

    Alias /juno "/home/juno/web"
    AddMonoApplications juno "/juno:/home/juno/web"
    # Uses a file under juno's home directory
-   MonoUnixSocket juno /home/juno/tmp/juno_server
    <Location /juno>
        MonoSetServerAlias juno
        SetHandler mono
    </Location>

You can set the file name to whatever you want as long as the user running apache has the necessary permissions to create and remove that file.

In order to run an instance of mod-mono-server that listens on a TCP socket, there’s a mandatory MonoListenPort directive and an optional MonoListenAddress. See them in action:

    LoadModule mono_module modules/mod_mono.so

    Alias /jazmin "/home/jazmin/web"
    AddMonoApplications jazmin "/jazmin:/home/jazmin/web"
    # 'jazmin' mod-mono-server will be listening on
    # port 9000, address 127.0.0.1
-   MonoListenPort jazmin 9000
    <Location /jazmin>
        MonoSetServerAlias jazmin
        SetHandler mono
    </Location>

    Alias /joan "/home/joan/web"
    AddMonoApplications joan "/joan:/home/joan/web"
    # 'joan' mod-mono-server will be listening on
    # port 7000, any address (0.0.0.0)
-   MonoListenPort joan 7000
-   MonoListenAddress joan 0.0.0.0
    <Location /joan>
        MonoSetServerAlias joan
        SetHandler mono
    </Location>

MonoUnixSocket and MonoListenPort are mutually exclusive.

Paths

In case it is needed, you can provide alternative locations for mono executable and mod-mono-server.exe. Other directories containing assemblies that mono could not find in the default search paths can also be specified. Mono needs a writable directory used by the windows I/O emulation layer that is usually in the user’s home .wapi directory ($HOME/.wapi). In mod_mono, the directory where .wapi is created is set to /tmp, but you can change that too.

    LoadModule mono_module modules/mod_mono.so

    Alias /jane "/home/jane/web"
    AddMonoApplications jane "/jane:/home/jane/web"
    # This uses mono 1.1.4 and ASP.NET 1.1 mod-mono-server
    MonoExecutablePath jane /nfs/mono-1.1.4/bin/mono
    MonoServerPath jane /nfs/mono-1.1.4/lib/mono/1.0/mod-mono-server.exe
    <Location /jane>
        MonoSetServerAlias jane
        SetHandler mono
    </Location>

    Alias /jackie "/home/jackie/web"
    AddMonoApplications jackie "/jane:/home/jackie/web"
    # This uses mono from SVN and the alpha ASP.NET 2.0 mod-mono-server
    MonoExecutablePath jackie /svn/install/bin/mono
    MonoServerPath jackie /svn/install/lib/mono/2.0/mod-mono-server2.exe
    # Add this directories to the default paths searched by mono
    # when looking for assemlies
    MonoPath jackie "/home/jackie/NET/assemblies:/usr/local/assemblies"
    # The .wapi directory will be created in /home/jackie
    MonoWapidir jackie "/home/jackie"
    <Location /jackie>
        MonoSetServerAlias jackie
        SetHandler mono
    </Location>

Troubleshooting

Access forbidden

If you’re getting a 403 response from apache that probably means that the user running apache does not have proper permissions to read the physical directory. Check the permissions on all the directories and the files and make then readable by the user running apache.

mod-mono-server does not start

Check the apache error_log file (/var/log/apache2/error_log …). It might contain some hints on what’s happening. Possible causes are that mono or mod-mono-server are not found in the path, that a file with the same name as the unix socket mod-mono-server tries to create already exists and mod-mono-server can’t remove it or a stale .wapi directory.

Introduction to Mono – Your first Mono app

The first in a series of articles about Mono. This article explains how to install Mono and shows how to compile your first Cross Platform application.

Introduction

Not so long ago the guys here at CP announced a new Cross Platform .NET section. At the time I was working completely with Windows based applications using C# and the .NET platform so, while the thought of getting to play around with C# apps on other platforms was interesting, it wasn’t something I had the time to do. Nevertheless, fate has once again stepped in, this time in the form of a new project, and soon I’ll be working on systems that will no doubt require some cross platform goodness. Since the majority of the development will still be for the Windows platform the technology set will be staying as is and the happiness that exists when developing .NET applications will remain.

Anyway, it dawned on me that I didn’t really know all that much about cross platform development with .NET. Sure, I had heard of Mono, Rotor and Platform.NET and had read some things here and there but I didn’t have any practical knowledge about using any of these. After a bit of research I decided that Mono was the most promising choice for the upcoming project and I decided to give it a go. I am fairly familiar with Linux and have developed applications, albeit basic ones, for Linux using C, C++ and Java when in college. However, many weblog postings from bemused Windows developers who had attempted to get Mono up and running on Linux had me slightly worried before I began. Much to my surprise, it was actually a painless experience and getting Mono running on Linux was easy. Setting it up and running it on Windows was even easier again.

What exactly is Mono?

When Microsoft unleashed .NET onto the world they were nice enough to hand the Common Language Infrastructure (CLI), along with the C# language, to the people at the European Computer Manufactures Association, better known to most as the ECMA. This allowed for an ECMA standards for the CLI and C# to be developed and, eventually, these ECMA standards also became ISO standards. At this stage you might be thinking “So, what has this got to do with what Mono is?” Relax, slow down, I’m getting to it. This standardization meant that details about how a CLI implementation should work, and also details about the C# programming language, where publicly available and anybody with the time and desire could implement their own CLI, essentially making their own version of .NET. Mono was born.

Mono is an “open source development platform based on the .NET framework that allows developers to build Linux and cross-platform applications with unprecedented productivity”. At the time of writing this article the latest stable version of Mono is 1.0.5 and it provides the following features:

  • A Common Language Runtime (CLR) that is compatible with the ECMA standard
  • A C# compiler
  • A set of class libraries
  • Ancillary tools such as a disassembler, debugger, IDE, etc.

Although it may not sound like much to many, what the people behind the Mono project have achieved is quite impressive. The set of class libraries available with mono include implementations of ADO.NET, ASP.NET, and System.Windows.Forms as well as many other aspects of the BCL that .NET developers will be familiar with. Added to this is the Gtk# library which is a fully featured library that allows for the development of GUI apps on top of the gtk+ toolkit. All in all, quite impressive.

With Mono you can develop and run .NET applications on Linux, Windows and other platforms. You can build and deploy ASP.NET application on Linux servers. You can even run applications that you compiled using the Microsoft C# compiler on the Mono runtime and vice versa.

What is the purpose of this article?

This article is the first in a series of articles that I will be writing about developing cross platform applications using Mono. Its purpose is to explain how to get up and running with Mono on Linux and on Windows. I’ll explain how you install Mono and then I’ll show you how to use the C# compiler to compile and run what might be your first cross platform .NET application. I’ll also list some of the ancillary tools that come with Mono. Finally, I’ll show how you can run applications created using Mono on the Microsoft .NET Runtime and vice versa.

Unfortunately I haven’t had a chance to play with Mono on a Mac so I won’t be covering it in this article. However I will try to cover it, along with Platform.NET, in a future article. No promises though.

What you need to know

This article is not going to show you how to program in C#. This is something that you will have to learn yourself. There are many good introductory articles here on CP that you can read to gain a firm understanding of the ins and outs of the language.

An understanding of what the .NET Framework and what it is is not necessary, but it would definitely be beneficial.

Lets get going

Before you can develop anything using Mono you first need to get it up and running on your desired platform. Since this article is in the Cross Platform .NET section and one of the main uses of Mono is the development and use of cross platform applications, I cover installing Mono on both Windows and Linux. I’ll look at installing on Windows first even though, to be perfectly honest, it’s a bit of a no brainer. As I mentioned above, the latest stable version of Mono at the time of writing this article is 1.0.5 and I will be working with this version. The download page for the latest Mono releases is http://www.mono-project.com/downloads/index.html[^] but I will be giving direct links to the files I download in each of the sections.

If you would prefer to skip installing Mono on Windows then you can go straight to the Installing Mono on Linux section below.

Installing Mono on Windows

The Windows version of Mono runs on Windows 2000 and above. I’m working on Windows XP Professional with Service Pack 2 installed. It probably doesn’t make a difference but I just wanted to mention it in case my instructions on installing Mono on Windows differs slightly from the procedure you need to follow for your own setup. Just follow these steps and you should be up and running in no time:

  1. Download the Mono Windows Installer from the Mono download page. The file I am working off is http://www.go-mono.com/archive/1.0.5/windows/mono-1.0.5-gtksharp-1.0.5-win32-0.1.exe
  2. The installer is a standard Windows installer so you can simply run it once it is downloaded by doubling clicking on it.
  3. Once the installer begins, click on next to go to the License Agreement page.
  4. You’ll probably notice on the License Agreement page that there are a number of different Licenses that apply to the different components of the install. While I understand that most people simply agree and click on next, it would be irresponsible of me if I didn’t recommend that you read the License Agreement before agreeing to it.
  5. Once you pass the License Agreement section you are presented with some general information about the install. The installer that I link to above mentions that it includes Gtk# and XSP (A Mono based web server that I will be looking at in the next article in this series) among other things.
  6. Click on Next and select the install location.
  7. Click on Next again to bring you to the Select Components page. You are free to customize your installation but as I will be using all the components of this install in other articles in this series I would suggest that you accept the default “Full installation”.
  8. Click on Next again and you can customize the name of Mono folder that appears in the Start Menu.
  9. If you have decided to do a Full installation or if you have installed XSP, the installer will now ask you which port you want the web server to listen on. Generally this will be port 8088 but you can change it to any free port on your system. When you are ready click on Next.
  10. Finally, click on Install to install and configure Mono on your Windows machine.

The above list of instructions is probably too verbose. Most people would have been fine just clicking on Next the whole way through. However, I normally take my time when installing things. You never know what people slip into an installer and it’s always good to know exactly what you have put on your machine.

At this stage you can keep reading and learn how to install Mono on your Linux machine or if you don’t have a Linux installation, or just want to develop on Windows for the time being, you can skip ahead to the Your Mono toolset section.

Installing Mono on Linux

Linux is a great operating system. There is no doubting that. However, there are some basic problems with the Linux platform that have stemmed from the fact that the kernel and most of the supporting software is open source. The problem is a simple one; there are so many different Linux distributions that there is no single set way of installing software on them. Why should you care about this? Well, depending on the distribution that you use, it could end up making your life a little more complicated then it needs to be when installing Mono. You’ll see what I mean below.

To get Mono up and running I decided to go for one of the more popular Linux distributions. Partly because I was familiar with it and partly because there was already an iso of the installation DVD on one of the internal FTP servers in work. No point in downloading a different distribution if I have a perfectly good one here. So, what did I choose? SuSE 9.2 Professional. I used Microsoft Virtual PC 2004 to create two identical virtual PCs. Two because I wanted to try two different ways of installing and configuring Mono that were not mutually exclusive. I didn’t want them to interfere so I decided that two separate virtual PCs was the way to go. I mounted the installation DVD iso in the virtual PCs and went about installing an identical system on both virtual PCs. I chose to install with ACPI disabled, which is one of the first options you get to choose, and I went for the default package selection. Nothing fancy. Just the basic, default system that SuSE 9.2 Professional suggested.

If you have a different Linux distribution (have a look at http://www.distrowatch.com/ for a good list of the different distributions available) then chances are that the installation instructions below will differ slightly for you.

The easy way

As the name suggests, this way is, well, easy. The problem with this way however, is that it will not work on all Linux distributions. If you have a look at the Mono download page (http://www.mono-project.com/downloads/index.html[^]) you will see that there are a packages available for some versions of the more common Linux distributions including Red Hat, SuSE, Fedora, and Novell Linux Desktop. Now a lot of Linux distributions will be compatible with some of these installation packages but specifying which ones are and which ones are not is well outside the scope of this introductory article. Unfortunately, if you are not using one of the listed distributions you’ll have to either find out from your distributions documentation which of the packages are compatibly or you can download the Mono source and build Mono from that (covered in the Not for the faint hearted section below). If you are not familiar with Linux I would recommend trying your best to avoid the latter option as it can get messy.

So, you have a Linux distribution that the Mono download page seems to like. Great. You’re in luck as this is going to be painless:

  1. On the Mono download page, click on the “Packages” link beside the Linux distribution that you believe to be compatible with your distribution. I simply selected the link beside SuSE 9.2
  2. This should bring you to a page which lists a lot of different packages that have been compiled and packaged for that particular Linux distribution.
  3. For the time being we are only interested in the “Mono Core Runtime and C# compiler” section in the top left.
  4. In this section you need to click on the download link for the Mono Core. The exact name will vary depending on the packages link that you selected but in general it will start with “mono-core-1.0.5”. I used http://www.go-mono.com/archive/1.0.5/suse-92-i586/mono-core-1.0.5-1.ximian.10.4.i586.rpm
  5. Download this file and remember where you have saved it!
  6. When it has downloaded simply open the file and it will launch the package manager for your particular distribution.
  7. From this point on you’ll have to follow the particular installation procedure for your package manager but in general there is simply an “Install Package” button. Click it!
  8. After a while, the Mono core should be installed. Congratulations

If you are inquisitive, bored, or if the above instructions didn’t work for your distribution then the next section runs over how to build and install from the source. In general this should be a painless procedure but as you will see, it turned out to be less then painless with the default SuSE 9.2 Professional install that I decided to work from.

When you went to the packages page you probably noticed downloads for Gtk#, XSP and a number of other things that the Windows installer installed by default. For the time being you can ignore these. In future articles I will need you to have these packages installed but if and when the need arises, I will run through the installation process.

Not for the faint hearted

If you have Mono installed on your Linux distribution at this stage then you can skip ahead to the Your Mono toolset section. That is, of course, unless you are interested in finding out how I spent two hours getting the source to compile.

Ok. So you want to compile Mono from the source and then install it. No problem. This “should” be a simple process. I have configured, compiled and installed applications from the source code numerous times on Linux without problem. Not this time. In this section I’m going to explain to you how things “should” work from the source. I’ll then show you how things worked for me when I configured, compiled and installed from Mono Source. Here goes:

  1. The first thing you need to do is download the source. Once again, head on over to the Mono download page at http://www.mono-project.com/downloads/index.html[^].
  2. In the source code section click on and download the Mono Runtime source (usually at the very top). The one I downloaded and worked off is http://www.go-mono.com/archive/1.0.5/mono-1.0.5.tar.gz.
  3. Once the file has been downloaded, go to a console for the remainder of the process.
  4. I would recommend performing the rest of the process as a user with root privileges. If you have just installed Linux as a standalone machine you can usually give your account root privileges by typing the sudo bash command and entering the root password.
  5. You can decompress the downloaded file using the command tar -xvzf mono-1.0.5.tar.gz where mono-1.0.5.tar.gz is the name of the file you downloaded.
  6. Next, switch to the directory where the source code has been decompressed too by typing cd mono-1.0.5 or cd followed by the name of the directory that you decompressed the file to if it is different from mine.
  7. Now, before we can compile the source you need to configure the make files. To do this simply type ./configure --prefix=/usr. This will take a bit of time. I am assuming here that there were no errors and that the ./configure --prefix=/usr went ahead without issue. As you will see from my experience, which I outline below, this was not the case for the default SuSE 9.2 Professional installation.
  8. When the the ./configure --prefix=/usr  completes you are free to go ahead and compile and install the source.
  9. To actually compile the Mono Runtime source you need to run the make command.
  10. Finally, to install, for lack of a better word, simply run the make install command. This will deploy the compiled binaries, libraries and other bits and pieces to the correct directories.

Now, that is how things should work. And, if I had installed a version of SuSE 9.2 Professional with the development tools installed, then that is what would have happened. However, as I have mentioned before, I opted for the default installation. I wanted to see how things would be for somebody who was coming from Windows and was more accustomed to OS installs that require the minimum of configuration.

The following, rather long set of steps, is what I had to do to configure, compile and install the Mono Runtime source. It not that it is a complicated process. Everything is actually quite simple. It’s just that it can be rather daunting to someone with very little Linux experience to see their initial ./configure --prefix=/usr fail when all the documentation for the Mono install tells them to do is type three commands: ./configure --prefix=/usr then make and finally make install. I was in two minds about whether I should add my experience with the Mono source as it is quite long and it might not add anything to the article. However, since I was having these issues I was sure that others would too and hopefully my experience can help you if you are faced with similar problems. Feel free to skip the rest of this section if you already have Mono installed.

So. Here’s what I done, and all just for you!:

  • Downloaded “Mono Runtime 1.0.5” from http://www.go-mono.com/archive/1.0.5/mono-1.0.5.tar.gz
  • Decompressed the download and then moved into the source directory.
  • Ran the sudo bash command to give myself root privileges.
  • Ran ./configure --prefix=/usr for Mono.
    • ./configure --prefix=/usr failed as default SuSE install does not have the needed compilers installed.
    • Installed Compilers (gcc c++ and it’s dependencies) using Yast.
  • Ran ./configure --prefix=/usr for Mono again.
    • ./configure failed because the default install does not have bison installed.
    • Downloaded bison from http://ftp.gnu.org/gnu/bison/bison-2.0.tar.gz.
    • Decompressed bison download and moved into the decompressed directory.
    • Ran ./configure for bison.
      • ./configure for bison failed because GNU m4 version 1.4 (or greater) is needed.
      • Downloaded m4 from http://ftp.gnu.org/gnu/m4/m4-1.4.1.tar.gz.
      • Decompressed m4 download and moved into the decompressed directory.
      • Ran ./configure for m4… Succeeded!
      • Ran make for m4… Succeeded!
      • Ran make install for m4… Succeeded!
    • Ran ./configure for bison, again… Succeeded!
    • Ran make for bison… Succeeded!
    • Ran make install for bison… Succeeded!
  • Ran ./configure --prefix=/usr for Mono for the third time.
    • ./configure failed, again, because “pkg-config” is needed and is not installed by the default SuSE 9.2 install.
    • Downloaded pkg-config from http://www.freedesktop.org/software/pkgconfig/releases/pkgconfig-0.15.0.tar.gz.
    • Decompressed pkg-config download and moved into the decompressed directory.
    • Ran ./configure for pkg-config… Succeeded!
    • Ran make for pkg-config… Succeeded!
    • Ran make install for pkg-config… Succeeded!
  • Ran ./configure --prefix=/usr for Mono for the fourth time!
    • Guess what?.. Yep.. ./configure failed again. This time because glib-2.0 (or greater) was needed and was not installed by the default SuSE 9.2 install.
    • Downloaded glib-2.6.1 from ftp://ftp.gtk.org/pub/gtk/v2.6/glib-2.6.1.tar.gz.
    • Decompressed glib-2.6.1 download and moved into the decompressed directory.
    • Ran ./configure for glib-2.6.1
      • ./configure for glib-2.6.1 failed because there was no “gettext” support in the C libraries installed in the system
      • Downloaded gettext 0.14 from ftp://ftp.heanet.ie/mirrors/ftp.gnu.org/gnu/gnu/gettext/gettext-0.14.tar.gz.
      • Decompressed gettext 0.14 download and moved into the decompressed directory.
      • Ran ./configure for gettext… Succeeded!
      • Ran make for gettext…
        • make for gettext failed because there is not C# compiler installed! WTF | :WTF: Confused | :confused:make suggests installing Platform.NET Roll eyes | :rolleyes:
        • Reconfigured gettext as there was no way I was installing Platform.NET just so I could install Mono.
        • Ran ./configure --disable-csharp for gettext… Succeeded!
      • Ran make for gettext, again… Succeeded!
      • Ran make install for gettext… Succeeded!
    • Ran ./configure for glib-2.6.1 again… Succeeded!
    • Ran make for glib-2.6.1… Succeeded!
    • Ran make install for glib-2.6.1… Succeeded!
  • Ran ./configure --prefix=/usr for Mono for the fifth time… Succeeded! Finally!
  • Ran make for Mono… Succeeded!
  • Ran make install for Mono… Succeeded!
  • Took a well earned breather.

The above set of steps that I had to go through to get the source compiled might seem a little daunting to some but to be perfectly honest it was an easy enough procedure. The main issue was the time taken. For example, the ./configure for Mono could take around 2 or 3 minutes each time. Each ./configure for the other items that had to be compiled and installed had similar time periods and generally speaking the make command took longer than its accompanying ./configure. There was also the time spent looking for, downloading and decompressing the source files for the different items that needed to be installed. Oh, and I had to actually restart SuSE before I could use the installed tools.

Your Mono toolset

At this stage you’ve either given up or you’re in for the long haul. Not that there is much left to do. We have Mono installed and the tools that we need to compile and run C# applications are ready to be used. Before we start to actually write and compile applications I thought it might be a good idea to have a quick overview of some of the tools the you should have available to you at this stage. I’m not going to go into any detail on the tools as in this article, and over the rest of this series, I will explain the details of the tools as they are needed.

Tool Description
disco Mono’s Web Service Discovery Tool
A tool for discovering web services and for retrieving the documents that describe those services.
gacutil Global Assembly Cache management utility
A tool used by developers to install assemblies into the system Global Assembly Cache (GAC) to become part of the assemblies that are available for all applications at runtime.
ilasm Mono IL assembler
The Mono IL assembler. Comparable to the Microsoft ilasm.exe tool.
mcs Mono Compiler Suite.
The Mono C# compiler, an implementation of the ECMA-334 language specification. The compiler accepts all the same command line options that the Microsoft C# compiler (csc.exe) does.
mint Mono Interpreter
A mono interpreter that allows for the execution of applications without using JIT. The instructions are interpreted directly into x86 instructions.
mono Mono’s ECMA-CLI native code generator (Just-in-Time and Ahead-of-Time)
A runtime implementation of the ECMA Common Language Infrastructure. This can be used to run ECMA and .NET applications.
monodis Mono assembly disassembler
A tool that allows applications to be disassembled into IL. Provides similar functionality to Microsoft’s ildasm.exe.
monograph Mono assembly information tool
A tool that allows you to create call graph or type hierarchy information from assemblies.
monop Mono Class Outline Viewer
A tool that allows you to view the outline of a class. You can see the signature of each member of the class.
sn Digitally sign/verify/compare strongname on CLR assemblies
Digitally sign, verify or compare, CLR assemblies using strongnames.
soapsuds Mono’s Remoting Proxy Generator
A tool for generating WSDL documents and client proxies for remoting services.
wsdl Mono’s Web Service Proxy Generator
A tool for generating proxy classes that can be used to access to web services.
xsd Mono’s utility for generating schema or class files
A tool that is intended to complement the XML serialization support of Mono.

Remember, this is only a subset of the tools that are available. If you are interested in exactly what tools are available you should have a look on the Mono homepage.

Also, when using Mono on Windows it would be a good idea to add the <Mono_Install_Dir>\bin\ and <Mono_Install_Dir>\lib\ directories to your path (C:\Program Files\Mono-1.0.5\bin\ and C:\Program Files\Mono-1.0.5\lib\ on my system). This will allow you to use the above tools directly from the command line regardless of which directory you are currently working in.

Let’s code!

About time! To get to this point should not have taken you all that long, unless of course you ended up installing Mono on Linux from source and ran into the trouble that I did. So let’s get on with it.

Hello World!

The proverbial “Hello World!”. You’ve no doubt seen a hello world application in C#, or other languages, numerous times in the past and you are once again going to see it. It’s kind of a tradition and who am I go against tradition?

Anyway, fire up your favorite text editor, be it notepad on windows or joe on Linux. Type in the code below, or even easier, copy it from the article and paste it in.

using System;

namespace Dela.Mono.Examples
{
   public class HelloWorld
   {
      public static void Main(string[] args)
      {
         Console.WriteLine("Hello World");
      }
   } 
}

Save this as HelloWorld.cs and get ready to witness the wonders of Mono. To compile this application simply go to the command line and type mcs HelloWorld.cs and hit enter. Note that the previous command assumes that your command prompt is working in the same directory as the HelloWorld.cs file and that the Mono directories have been added to your path if you are using Windows. If all goes well you should be presented with the “Compilation succeeded” text. Congratulations. You’ve just compiled your first C# application on Mono.

To execute the application using Mono simply type mono HelloWorld.exe and hit enter. You’ll be greeted by the text “Hello World”. What you have done here is loaded the Mono JIT Runtime which JIT compiled the IL code inside the HelloWorld.exe assembly and executed the instructions. You could have also executed the application by running mint HelloWorld.exe. This would have used the Mono Interpreter to convert all the IL of the application directly to x86 instructions before executing. This is similar to using the ngen.exe application with .NET.

If you are running Mono on Windows you may have noticed that you can also execute the application by simply double clicking on it. You may not see this as being special in any way but what you have done is taken an application created with the Mono C# compiler and executing it on the Microsoft .NET Runtime. More about this below in the .NET and Mono interoperability section.

Something a little more complicated

Hello World is the traditional first program, but in all honesty it doesn’t really do much. The next example is a bit contrived but it shows a few more of the features of Mono including the System.Net, System.Text, and System.Text.RegularExpressions namespaces. I also know that the code is all lumped into the Main method and that it should be refactored but as I said, this is just a contrived example, and not a lesson in code style.

The example simply takes a string that you want to search on http://www.google.com/ for and then displays the first five results that comes back. Nothing major but it does show an ever so slightly more complicated example than the Hello World example above. Anyway, once again, fire up your favorite text editor, type in the code below or copy it from the article and paste it in.

using System;
using System.Net;
using System.Web;
using System.Text;
using System.Text.RegularExpressions;

namespace Dela.Mono.Examples
{
   class GoogleSearch
   {
      static void Main(string[] args)
      {
         Console.Write("Please enter string to search google for: ");
         string searchString = HttpUtility.UrlEncode(Console.ReadLine());
         
         Console.WriteLine();
         Console.Write("Please wait...\r");

         // Query google.
         WebClient webClient = new WebClient();
         byte[] response =
              webClient.DownloadData("http://www.google.com/search?&num=5&q="
              + searchString);

         // Check response for results
         string regex = "g><a\\shref=\"?(?<URL>[^\">]*)[^>]*>(?<Name>[^<]*)";
         MatchCollection matches
                  = Regex.Matches(Encoding.ASCII.GetString(response), regex);

         // Output results
         Console.WriteLine("===== Results =====");
         if(matches.Count > 0)
         {
            foreach(Match match in matches)
            {
               Console.WriteLine(HttpUtility.HtmlDecode(
                  match.Groups["Name"].Value) + 
                  " - " + match.Groups["URL"].Value);
            }
         }
         else
         {
            Console.WriteLine("0 results found");
         }
      }
   }
}

Save this file as GoogleExample.cs and go back to the command line. The command to compile this application is a little different to the one we used for the Hello World example. This application makes use of the HttpUtility class which is defined in the System.Web.dll assembly. That means we need to reference this assembly when compiling. To do this you simply use the -r switch. This is the full command you need to type to get this application to compile: mcs GoogleExample.cs -r System.Web.dll
Once again, the previous command assumes that your command prompt is working in the same directory as the GoogleExample.cs file and that the Mono directories have been added to your path if you are using Windows.

As with the Hello World example you can run this application from the command line using mono GoogleExample.exe or mint GoogleExample.exe – Take your pick. The same compiled assembly will run on Windows and Linux. You can test this by compiling it on Windows, copying the assembly to a Linux machine and running the mono GoogleExample.exe command there.

.NET and Mono interoperability

I mentioned in the Hello World example above that you can simply take the assembly created by the Mono compiler (HelloWorld.exe in that example), double click on it in a Windows environment with .NET installed, and it would execute. How exactly does that work? Well, it’s simple really. The Mono C# compiler, and the Microsoft C# compiler, compile code into an intermediary form known as IL. When you execute an assembly the runtime interprets and executes the IL code. So you can take an assembly compiled from VB.NET code, or any .NET language, and run it on Mono and vice versa. There is however one small issue with this; Mono doesn’t have a complete implementation of the .NET class libraries so not all of your applications can be run using Mono. Don’t worry too much about that now as over the next few articles in this series we’ll see what can and can’t run and hopefully examine why.

What next?

Hopefully this article has shown you how to install Mono and get your first Mono applications up and running on Windows and on Linux. That’s not all that much though. You’ll obviously want to do more than just create simple console applications. As I’ve said throughout this article, this is just the first in a series of articles that I’ll be writing about Mono and Cross Platform .NET development using Mono. So, what’s on the cards for the next article? Well, I know it would probably be best to jump in a start creating cross platform GUI apps but before we look at this I want to do an introduction to Web Application and ASP.NET development using Mono, which is what the next article will be about; writing your first ASP.NET application that runs on both Linux and Windows.

Links

History

June 8th, 2005 – Corrected details about Mono tool “mint”.

March 1st, 2005 – Updated some language mistakes and changed to install Mono in the /usr directory when installing from source on Linux.

January 25th, 2005 – First Posted.

How-to: mod_mono

Do the following on CentOS/Fedora/RHEL before starting the installation:

Code:
yum -y install libungif-devel freetype-devel libtiff-devel libjpeg-devel xulrunner-devel

Installation:

Code:
cd /root
mkdir mono
cd mono
wget http://origin-download.mono-project.com/sources/mono-1.1.16/mono-2.11.1.tar.bz2
tar xjf mono-2.11.1.tar.bz2
wget http://origin-download.mono-project.com/sources/xsp/xsp-2.10.2.tar.bz2
tar xjf xsp-2.10.2.tar.bz2
wget http://origin-download.mono-project.com/sources/libgdiplus/libgdiplus-2.10.9.tar.bz2
tar xjf libgdiplus-2.10.9.tar.bz2
wget http://origin-download.mono-project.com/sources/gluezilla/gluezilla-2.6.tar.bz2
tar xjf gluezilla-2.6.tar.bz2
wget http://origin-download.mono-project.com/sources/mod_mono/mod_mono-2.10.tar.bz2
tar xjf mod_mono-2.10.tar.bz2
cd mono-2.11.1
./configure --prefix=/usr
perl -pi -e 's/HAVE_LOCALCHARSET_H 1/HAVE_LOCALCHARSET_H 0/' eglib/config.h
make -j 8
make install
cd ../xsp-2.10.2
./configure --prefix=/usr
#skip the next line on FreeBSD
export PKG_CONFIG_PATH=`whereis pkgconfig | awk '{print $2}'`
#skip the next line on CentOS/Debian/Fedora/Ubuntu
setenv PKG_CONFIG_PATH `whereis pkgconfig | awk '{print $2}'`
make
make install
cd ../libgdiplus-2.10.9
./configure --prefix=/usr
make
make install
cd ../gluezilla-2.6
./configure --prefix=/usr
make
make install
cd ../mod_mono-2.10
./configure --prefix=/usr
make
make install
ldconfig
echo '#mod_mono' >> /etc/httpd/conf/extra/httpd-includes.conf
echo 'Include /etc/httpd/conf/mod_mono.conf' >> /etc/httpd/conf/extra/httpd-includes.conf
#skip the next line on FreeBSD
/etc/init.d/httpd restart
#skip the next line on CentOS/Debian/Fedora/Ubuntu
/usr/local/etc/rc.d/httpd restart

install_mono.sh

Install mono on centOS 6.x

$ yum install bison gettext glib2 freetype fontconfig libpng libpng-devel libX11 libX11-devel glib2-devel libgdi* libexif glibc-devel urw-fonts java unzip gcc gcc-c++ automake autoconf libtool make bzip2 wget
$ cd /usr/local/src
$ tar jxf mono-3.2.8.tar.bz2
$ cd mono-3.2.8
$ ./configure –prefix=/opt/mono
$ make && make install
$ export PATH=$PATH:/opt/mono/bin
$ export PKG_CONFIG_PATH=/opt/mono/lib/pkgconfig
$ # make sure to add the previous two lines to your ~/.bash_profile

My Adventures Installing mono 2.0 on CentOS 4 to work with apache via mod_mono

My Adventures Installing mono 2.0 on CentOS 4 to work with apache via mod_mono

Apparently the good folks over at the mono project decided to discontinue binary packages for the Red Hat line of linux distributions.  It’s a shame in a way, there are a lot of those installation out there, so it would be nice to keep things updated through yum or apt-install or rhupdate, etc..

On the up side, installing from source has never been easier.  In the past I have went through many hours of trying to get the right versions of different libraries that were needed.  With the official release of 2.0 it seems much better.  I thought I would share the steps that I went through.

Disclaimer: This worked on a fairly fresh install of CentOS 4.7.  I have not tried it on 5.x, nor on any other flavor of linux (SUSE, Ubuntu, etc..) so your mileage may vary.

At the time of the install (and this writing) the current mono stable version is 2.0.1 so all references will be to that version.  Here are the steps that I went through.

Preparation

Always be prepared – Boy Scouts motto…

In rooting around the web I did find a few helpful pointers.  First, make sure you have gcc installed.  Now this is one of those duh pieces of information, but in the fairness of completeness I thought I would mention it. (Note: If you do not have gcc or bison, install them! Credit The_Assimilator’s comment)

# yum install gcc-c++
# yum install bison
Next I installed the httpd-devel package.  I had read (will find the link later) that it helps some of the installation down the line.  In my case I just use yum to install it. (Note:  httpd-devel package is required by the mod_mono compile if apxs (Apache Extension Tool) is not on your machine. credit to The_Assimilator’s comment)
yum install httpd-devel

You may also require the glib-2.0 libraries (thanks to Michael Walsh for that bit).  If you receive the error “Package glib-2.0 was not found in the pkg-config search path” you can install it via yum as well.

yum install glib2-devel

The Main Dance

Next comes the meat of the installation.  First, I downloaded the necessary source packages.  I simply used wget to snag the core mono package, xsp (mono web server) and mod_mono (apache integration).

wget http://ftp.novell.com/pub/mono/sources/mono/mono-2.0.1.tar.bz2
wget http://ftp.novell.com/pub/mono/sources/xsp/xsp-2.0.tar.bz2
wget http://ftp.novell.com/pub/mono/sources/mod_mono/mod_mono-2.0.tar.bz2

Next we install the mono core

tar -vxjf mono-2.0.1.tar.bz2
cd mono-2.0.1
./configure
make
make install
cd ..

Next comes xsp

tar -vxjf xsp-2.0.tar.bz
cd xsp-2.0
./configure
make
make install
cd ..

At this point I recevied an error (I believe it was in the make process) that the compiler could not find the file dotnet.pc.  I found that it was indeed on my system so I simply had to export the path and then finsih the compile.

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
make
make install
cd..

Note: Make sure the file dotnet.pc is in that location.  If not, adjust the path above.

Finally we install mod_mono

tar -vxjf mod_mono-2.0.tar.bz2
cd mod_mono-2.0
./configure
make
make install

There, easy huh?

Configuration

You may want to verify a few thigns to make sure the configuration is ready to rock.  In my case, I am keeping the mono configuration in a separate file for sanity sake.  You can do that or put it all in your httpd.conf, it’s up to you.

<IfModule !mod_mono.c>
    LoadModule mono_module /usr/lib/httpd/modules/mod_mono.so
    AddType application/x-asp-net .aspx
    AddType application/x-asp-net .asmx
    AddType application/x-asp-net .ashx
    AddType application/x-asp-net .asax
    AddType application/x-asp-net .ascx
    AddType application/x-asp-net .soap
    AddType application/x-asp-net .rem
    AddType application/x-asp-net .axd
    AddType application/x-asp-net .cs
    AddType application/x-asp-net .config
    AddType application/x-asp-net .Config
    AddType application/x-asp-net .dll
    DirectoryIndex index.aspx
    DirectoryIndex Default.aspx
    DirectoryIndex default.aspx
</IfModule>
That was it.  I hope that helps!