MVC2 on Mono – Tips and Tricks for Windows Developers
MVC2 on Mono – Tips and Tricks for Windows Developers
So lately, I’ve been pretty wrapped up with kids and family so I haven’t had much time to post anything new. However, I did start a new project, which I’ll detail out more as I go. It’s been quite the experience so far since I decided to build this one from the ground up using MySql and Linux/Mono. I’ve never designed apps like that before. For one, I’ve had to learn a new set of design tools for MySql as opposed to my comfortable Sql Management Studio. And I’ve also had to very incrementally test different programming technologies and methods that were questionably supported in Linux/Mono. The beauty of this is that no matter what I do to make it work for Mono, the app will always work on Windows, and there’s little development time lost if I have to fall back to its native platform.
So about this project… Well it’s a simple project really: web based, MVC2 with a MySql database. So here’s a few technical issues I ran into while building the beginnings of this application.
Choosing a Data Framework
I know some of you purists would say stick to vanilla ADO.NET; it works every time, and you have no conversion problems. Well, that’s right, but I’m a lazy typist, and I really dig LINQ. So I tested several LINQ data frameworks on mono and found that Dblinq and SubSonic3 were the most functionally supported frameworks. I tested it with Linq to NHibernate, but it didn't work. SubSonic3, after a recent bug fix, now does work in Mono!
MVC2 Works on Mono?
Yeah it does! Well mostly and only if you pull from the trunk code or the daily tarballs. Unfortunately, it does not work with the latest public release 2.6.4 and definitely not 2.4.4 which is the latest deployed version on Ubuntu 10.04. MVC2 now is officially supported by the Mono 2.8 release. MVC1 does work out of the box on older versions of Mono (2.6). So what do you have to do to get it working? Until Mono 2.8 gets pushed into the packaging system, you'll need to learn a little bit about compiling Mono on your own and installing it, which sounds more painful that it really is. I wrote a script that works (most of the time) on Ubuntu. There’s no guarantee that it will work for you of course.
Checkout one of my recent posts about manually getting Mono 2.8 installed.
Using MVC2 is the easy part. Just setup a new MVC2 project and ensure your reference options for the System.Web.Mvc and System.Web.Routing assemblies are set to Copy Local. Data annotations will not work, so you’ll need to rip out the model validation in the default MVC2 project; otherwise, the rest of it works like a charm.
xUnit and Dependency injection with Unity works too!
Yup, believe it or not, some of the components in the Enterprise Library do work in Mono including Unity, which works great for swapping out mock classes in test projects. I chose to use xUnit as my testing framework since it seemed to work pretty nicely in the SubSonic project. I also found a real nice breakdown of how they compare to other testing frameworks. The xunit command line runs on vanilla Ubuntu 10.04 (mono 2.4.4). However, my preferred method of running some of these tests is using the TestDriven.net runner on Windows/VS.
System Agnostic Gotchas
I’ve built and tested most of it on Windows. Which sometimes creates problems when deploying to non-Windows servers. Especially when it comes to I/O pathing. As you go through and design it, you always have to build it in a platform agnostic manner. Duh right? This includes simple things like case senstive paths, using the correct directory separators, etc. Typically as lazy Windows programmers (not all of us)
we would rather hard code the path separator like this. string.Format(@“..\files\{0}”, filename); But unfortunately that breaks Linux pathing. So by using Path.DirectorySeparator, it will automatically decide which is the correct character to use on either platform.
string.Format(“..{0}files{0}{1}”, Path.DirectorySeparator, filename);
The later versions of windows also support both slashes, so you could get away with using forward slashes in windows I/O on Vista and 7.
It can be advantageous (if working with a web application) to use System.Web.HttpContext.Current.Server.MapPath or System.Web.Hosting.HostingEnvironment.MapPath to get your native local path from a virtual one. So store your paths as virtual ones and let the framework convert it to a native/local one.
Image Rendering
Well, I haven’t completely dug into this, but I have briefly tested simple things like resizing images and writing them back out with Jpeg encoding. I have to say that the Mono built-in implementation of the GDI works just fine. I even tested some other things like rendering speed as far as resizing a jpeg and writing it out. It seems using the System.Drawing as opposed to Mono’s GDK/Cairo actually works faster (only by observation; nothing official). I’ll have more detailed results on this as I get to that piece.
Wrap-Up
So if you’re interested in starting a new Mono project, I hope some of these tips will keep you out of trouble. Good Luck!

9 Comments
Model validation is also possible. You just need to add the System.ComponentModel.DataAnnotations.dll assembly from 3.5 to your bin dir and it is working like a charm.
@Sumit Birla
And you’re right. It is just on linux. I tested this successfully (the Linq with joins worked) with Mono 2.6.4 on windows. I’m using the latest master subsonic branch, and I’m connecting to a mysql server and using the exact same build for all three scenarios.
@Sumit Birla
Yeah, I did notice this just the other day. I’ve been working around it for now but have intentions of investigating that. I tested both linq and lamba expressions and got the same end result. I’ll post it as an issue if there isn’t one already.
Are you able to perform joins using SubSonic + Linq? Always throws an exception for me… even tried with the upcoming Mono 2.8.
@jmalcolm
Ah yeah. Also per the GDI stuff. I did some more test against that recently and found the only thing that didn’t work (of the apis I was using), was a text warp along a GraphicPath. However, the rest of the GraphicPath drew just fine. I’ll be testing more stuff like alpha blending, image overlays and resizing too; most of these are just basic web imaging tools I use for custom handlers or captchas.
@jmalcolm
Thanks jMalcom! I really like to hear how other folks use these tools. I agree with you. I recently started playing around with MonoDevelop and it’s a pretty impressive tool. I’ve even used it to build some tiny proof of concept apps for testing on Mono.
I mentioned SubSonic in this post not working. I recently (yesterday) found that a patch has been made to SubSonic a couple weeks ago that fixed it so it now runs on Mono. I’m in the middle of a huge refactor on a project converting it from Dblinq to SubSonic3. I’ll post a new blog about that when I test it and make sure it works 100%. But bottom line is that SubSonic repository mode supports using POCO objects and dependency injection for mocking. It’s very similar to how Nhibernate maps objects to databases, but it does it with a lot less control; the result is a very, very flexible and easy to use data framework.
Thanks for your comment. Keep them coming.
Thanks for sharing. It was interesting to see your take coming from Windows to Mono. I myself started on Linux and adopted Mono first before doing any .NET on Windows so the perspective is a little different.
Great cross platform suggestions.
I use MonoDevelop on Linux and so I tend to use it on Windows as well. NUnit integrates really nicely (ships with MonoDevelop) so that is what I tend to use for unit testing. Being more in the Linux/Open Source camp I would also have gravitated to NHibernate as the ORM and Castle Windsor for IOC. I think your post is going to make me take a look at Unity since I should really know the MS stack better. Funny that I should say that given that I code in C# every day.
Of course, you can still develop on Windows and deploy to Linux. You should not have to give up your favourite DB tools on Windows if you do not want to. I now develop on Windows sometimes myself just because their are a few dev tools that I like from there. This is why I use MonoDevelop. I can bounce back and forth between Windows, Linux, and Mac while keeping a familiar IDE which integrates well with both Subversion and NUnit on all platforms.
Compiling Mono on Linux is a breeze. It is getting libgdiplus up first which is a pain and it is a prerequisite since that is how Mono emulates GDI+ on Linux.
Compiling Mono is just ‘./configure && make && make install’ for the most part. Libgdiplus has a tonne of graphics library dependencies though (libtiff, libjpeg, libpng, libgif, etc).
At least you only have to install the dependencies once. After that, rebuilding new versions of Mono is very easy.
@C Sullivan
Thanks! Yeah I also recently just learned about a Windows MySql tool called TOAD. I’ve heard of it before for Oracle, but never tried it out. It’s very, very cool! It supports version control for your database to subversion, data compare, schema compare and a host of other really nice features. I still use the MySql GUI tools for Server admin, but this is a great tool for development.
Congratulations, this was an interesting read.
Recent Posts
Tags