While there are a myriad of reasons why your ASP.NET C# might not be working after a clean install in Linux, there is a very common problem that will prohibit Mono from working because of version 2.0 vs 4.0 issues. Typically this occurs on source code installations as opposed to package installs (particularly in CentOS / RHEL / Amazon Linux, not so much in Debian distributions).
You will see evidence of this crop up in your /var/log/httpd/error_log with an error message that looks like:
Cannot open assembly ‘/usr/lib/mono/2.0/mod-mono-server2.exe’: No such file or directory.
Fortunately there’s an easy fix.
As you can see the issue is that your software is looking for ASP.NET 2.0 instead of 4.0 and no, while at first you might think that there is some setting incorrectly looking for a Windows executuable instead of a Linux binary, that is incorrect. The Mono team decided strangely enough to have their linux executables named with the .exe extension. A bizzare choice in my opinion, likely made to make Windows developers feel more at home when working in the Linux environment.
Regardless, there are two methods to fix this.
While the method I am going to show you is probably not the cleanest method, it is the easiest. Technically the right way would be of course to install your software to look for ASP.NET4.0 instead of the older 2.0 – however, in my experience this is actually unnecessary. If you had a 4.0 >> 2.0 issue, then there would be cause for concern.
If you look in the /usr/lib/mono directory you should see something like:
drwxr-xr-x - root 7 Sep 15:19 2.0-api drwxr-xr-x - root 7 Sep 15:19 3.5-api drwxr-xr-x - root 7 Sep 15:19 4.0 drwxr-xr-x - root 7 Sep 15:19 4.0-api drwxr-xr-x - root 7 Sep 17:24 4.5 drwxr-xr-x - root 7 Sep 15:19 4.5-api drwxr-xr-x - root 7 Sep 15:19 4.5.1-api drwxr-xr-x - root 7 Sep 15:19 4.5.2-api drwxr-xr-x - root 7 Sep 15:19 4.6-api drwxr-xr-x - root 7 Sep 15:19 4.6.1-api drwxr-xr-x - root 7 Sep 15:19 4.6.2-api drwxr-xr-x - root 7 Sep 15:19 4.7-api drwxr-xr-x - root 7 Sep 17:00 gac drwxr-xr-x - root 7 Sep 15:19 lldb drwxr-xr-x - root 7 Sep 15:20 mono-configuration-crypto drwxr-xr-x - root 7 Sep 15:20 monodoc drwxr-xr-x - root 7 Sep 15:20 msbuild drwxr-xr-x - root 7 Sep 15:20 xbuild drwxr-xr-x - root 7 Sep 15:20 xbuild-frameworks
Notice that there is no 2.0 directory, and that the latest version installed is actually 4.5.
So we create a soft link to the latest installed version (4.5), referencing the old version that is being sought (2.0):
# ln -s 4.5 2.0
Then we should see:
lrwxrwxrwx 3 root 7 Sep 17:23 2.0 -> 4.5 drwxr-xr-x - root 7 Sep 15:19 2.0-api drwxr-xr-x - root 7 Sep 15:19 3.5-api drwxr-xr-x - root 7 Sep 15:19 4.0 ...
The next step is to enter the /usr/lib/mono/4.5 directory
... .rwxr-xr-x 442k root 7 Sep 15:20 mkbundle.exe .rwxr-xr-x 198k root 7 Sep 15:20 mkbundle.pdb lrwxrwxrwx 70 root 7 Sep 17:00 mod-mono-server4.exe -> ../gac/mod-mono-server4/4.2.0... .rwxr-xr-x 4.1k root 7 Sep 15:20 mod.exe .rwxr-xr-x 500 root 7 Sep 15:20 mod.pdb .rwxr-xr-x 76k root 7 Sep 15:20 mono-api-html.exe ...
Where we can clearly see that there is a mod-mono-server executable, however it is version 4 (in my case) and not version 2 which is what everyone is looking for. It also happens to be a soft link. No worries!
We create another soft link to that one (normally I am not a fan of double-linking, but this is the easy method remember? You can decide how you want to implement this yourself).
# ln -s mod-mono-server4.exe mod-mono-server2.exe
Voila! You shouldn’t even have to run sudo service httpd restart
If someone knows of an easier method to have Apache / mod_mono look for version 4.x instead of the old 2.0, I would dearly love to see it. (I will also gladly update this article).
Frankly its obvious this is an ugly [though simple] hack. What’s important is that it works.
The only issue I could see is where you have code that is legitimately 2.0, and needs to be run through a 2.0 interpreter. Honestly my recommendation is: you should upgrade your code. This may not be an option if you are using some large or significant legacy framework I understand.
Of course the simplest solution if you only need ASP.NET 2.0 is to download the correct library. I wouldn’t even know how to concurrently run multiple version of Mono anyways, so as far as I can tell, you have to settle on a single solution, and using the latest one is the smartest choice.