Email in Castle Monorail 2.0

Castle Monorail has been my web framework of choice for some years now. I’ve been using the obsolete RenderEmailAndSend method as that was how it is done in the sample code. Monorail 2.0 uses Core 1.2 which features an integrated email sender component, and the old sample code does not work anymore since Castle.Components.Common.EmailSender.Message has been removed.

The “new” way of sending isn’t documented officially anywhere, hence this blog post.

First, you’ll want a NVelocity template in the ViewsMail folder. We’ll call it Hello.vm:

subject: Hello!
from: $from
to: $to

Hello $name, this is a message from $site

Now for the controller, which we’ll name EmailController.cs (I’m not very imaginative):

using Castle.MonoRail.Framework;

namespace MonorailEmailSample.Controllers
    public class EmailController : Controller
        public void Send()
            PropertyBag["from"] = "[email protected]";
            PropertyBag["to"] = "[email protected]";
            PropertyBag["name"] = "Your Name";
            PropertyBag["site"] = "";

            DeliverEmail(RenderMailMessage("hello", null, PropertyBag));

            RenderText("Email sent!");

That’s it. The RenderMailMessage method signature I’m demonstrating is RenderMailMessage(string templateName, string layoutName, IDictionary parameters). We don’t need a layoutName if we are sending a plain text email which we are doing, hence we are passing in null.

Of course, you’ll want to set up your SMTP server properly in your monorail config section as per the instructions.

Castle ActiveRecord Bug?

Or perhaps it was actually NHibernate at fault. I was trying to set up a many-to-many relationship with attributes on the association table and the ActiveRecord CreateSchema call just kept complaining that my assocation table already exists and cannot be created again.

After an hour or so of head-scatching, turns out the error only occurs when I use GUIDs as the primary key in the association table. Switching to good old "int" solved everything. I wonder if that has been fixed in the trunk, I should go code spelunking.