Thursday, June 30, 2016

Deploying a ASP.NET MVC Application on Mono

Ever tried to deploy an ASP.NET MVC application before? Well, it's the bee's knees... on Windows, where most Visual Studio project types are first class citizens of the ecosystem (sorry, F#). However, things get a tad trickier on Linux / Mono, so let's run through the very basics of setting up an environment like this.

This post will not cover advanced topics, such as setting up an SSL certificate or linking with a database. It will just get the barebones ASP.NET server deployed. Note, however, that there are better ways to deploy an ASP.NET MVC service than what this post describes (through fastcgi or mod_mono), so if you're concerned about the RIGHT way of doing things rather than the FAST way of doing things, follow that link.

Structure - Skip if you have a project
Let's make ourselves an ASP.NET MVC application in Monodevelop. If you don't already have monodevelop, you'll need to install the following packages:

  • monodevelop
  • xsp
  • mono-devel
from your distribution's repository. If some of those aren't found, it may be okay, as both tend to be bundled with monodevelop itself. Now, make an ASP.NET MVC project with Razor

this should create an ASP.NET MVC project that's ready for deploying.

Now, it's time to compile the project. This is where a program from mono-devel comes into play. xbuild, an implementation of msbuild (link)  is what will generate what the web server runs. The binaries are generated from the .sln or .csproj file itself.

So, open up a terminal and go to the project root, where your project file is.
Then issue the "xbuild" command on your file. This will build all targets for the project, which are Debug and Release by default in Monodevelop

xbuild {file.sln}

Wonderful! If everything in your project passes, you have successfully built your ASP.NET MVC application

Now, here are where the tough decisions are made. If you are truly deploying a production service, you should do the following things:

  • Secure a webserver, preferably a dedicated virtual machine
  • Generate SSL certificates / other cryptographic keys
  • Create a user for running your service
  • Install the fastcgi-mono or mod_mono (apache) modules and run your service from Apache

However, the quick-n'-dirty way I do it is with xsp4. xsp is yet another pet project of Mono's, that aims to be a fast ASP.NET web server for development. However, there is nothing that says you can't use it in production. It allows SSL certificates, variable ports, etc. so you won't find yourself missing too many features from Apache.

Running xsp4 is dead simple. Go to the build directory (the one under your project root) and run "

xsp4 --port 80"

if all goes well with this, you should have a full-fledged ASP.NET MVC 4 application deployed under Linux, and available on the standard http port. This is, of course, the unsecure, bare-bones deployment with xsp4. But it's a good starting point. To find out how to make xsp4 handle errors, set up your certificates, etc. issue the command 

xsp4 --help

Hope you found this useful!

Wednesday, June 29, 2016

Using SQLite server with C# / Mono on Linux

If you've arrived on this post, it means that you're using Mono on Linux and attempting to use SQLite, and having a bit of difficulty. That's understandable. This is not a tutorial on SQL / Mono / Entity or anything of the sort. This will get a barebones implementation of a server working with mono.

The Problem
The problem is that Mono comes with Mono.Data.Sqlite. Yet, if you're looking for information on using SQLite in C#, you will be directed to use System.Data.Sqlite, which is included in the nuget library. You can add this using Xamarin's tools successfully. Intellisense should work, and most functions in System.Data.Sqlite should work as well... except for one: SQLiteConnection, which is used to connect to the database.

I'm not 100% positive on the nature of the problem, as it stands, in mono right now. I can narrow it down to (at least in my case) some kerfuffle regarding sqlite.interop.dll not playing nicely with my architecture of choice (x86_64).

The Fix
The best fix for this is to... use Mono.Data.Sqlite. However, this has some downsides.
  • Using a Mono library breaks compatibility with .NET... ouch.
  • Mono.Data.Sqlite, for whatever reason, is not a drop-in replacement of System.Data.Sqlite.
with these things in mind, let's do it.

using System;
using Mono.Data.Sqlite;
namespace SQLITETEST {
  class MainClass {
    SqliteConnection db = new SqliteConnection("Data Source={filename.sqlite};Version=3;");
    SqliteDataReader reader = new SqliteCommand("SELECT x FROM y WHERE z = zz;", db).ExecuteReader();
    while (reader.Read()) { Console.WriteLine(reader.GetString(0));}

and there you go. This code will connect to a database {filename}, run a query, and return the results. If you have experience with System.Data.Sqlite, you should notice that the SYNTAX of Mono.Data.Sqlite doesn't differ from it too much... but the spelling does. System.Data.Sqlite prefers to use classes spelled as "SQLiteDataReader, SQLiteConnection", etc. while Mono uses "SqliteDataReader"... 

While this seemingly unnecessary difference is annoying, it's negligible. Enjoy kludging through Sqlite and Mono further!