MonoRail


MonoRail & PHP05 Apr 2008 04:47 pm

First, I get the irony of posting this on a blog engine written in PHP…

In the past month or two, I’ve had to dig into the sources for a few different PHP projects. It’s not been fun… Though I’m admittedly ignorant about PHP’s various MVC frameworks, none of the apps I’ve been debugging have used one. The result? More spaghetti than found in all of Italy… Chasing down bugs through endless layers of includes and seemingly convention-less folder structures has soured me on a language I once wanted to learn.

One project I’ve been debugging has a strange path through an error handler that leads to a 404 header being written, hiding the original error completely behind a ‘File Not Found’ page. OK, so I know this is nothing PHP specific, but trying to trace down the original error has been a nightmare. This project, which has been a tremendous help to me as an adjunct, is well supported and in widespread use. But wow, it gets hairy trying to trace through the code…

I’m sure that PHP can be used effectively, and maybe even be made elegant. But I wonder why anyone making a platform choice for a new project would opt for PHP. Castle’s MonoRail has totally sold me on the value of a convention-oriented MVC framework. Debugging a MonoRail app is a predictable and rather pleasant experience. If static typing isn’t your thing, then TurboGears looks nice from what I’ve seen. I’ve been digging Ruby, but haven’t worked with Rails. I’m looking forward to writing my next personal project with Rails though.

Castle & MonoRail16 Feb 2008 04:02 pm

Helpers in MonoRail provide a very convenient way to extend your presentation logic. However, it’s important to note that MonoRail will initialize helper instances for a controller before the session state has been created for the request. The implication of not having session state when helpers are initialized is that you cannot check session state in a helper’s constructor. Consider the following:

[Helper(typeof(SomeHelper))]
public class SomeController : Controller
{
       public void SomeAction() {}
}

public class SomeHelper: AbstractHelper
    {
        public SomeHelper()
        {
            if (HttpContext.Current.Session["SOME_KEY"] != null)
                doSomething();
        }
}

When the request for /SomeController/SomeAction.rails is processed, the SomeHelper instance will be created. When the constructor code executes, a null reference exception will occur when attempting to access an item in session. The obvious implication is that any initialization code that is session state dependent cannot be in the constructor. The solution I’ve used is to create an initialize method that is called from any method requiring the setup routine.

Update 2008-02-21 - this issue cropped up with controllers too. Session is not created at the time controllers are instantiated either. Avoid constructors that check session state.

.NET & MonoRail19 Jan 2008 11:39 am

MonoRail’s SmartDispatcherController will automatically bind controller method parameters to request parameters. So the arg0 and arg1 parameters in the method below -

public void DoSomething(string arg0, int arg1)
{
...
}

will have the values castle and 5 respectively when the request is constructed like

/SomeController/DoSomething.rails?arg0=castle&arg1=5.

While this is certainly a useful feature, it’s important to remember that any item in the Request.Params collection is a candidate for binding. At work, my team and I recently ran into a problem where this behavior resulted in some unexpected exceptions.

The site running MonoRail has some classic ASP that’s being phased out, but is still accessed during a visitor’s session. During the ASP flow, some session cookies are set. One of these cookies happens to share the name of a parameter in one of our controller methods. When this controller action was hit, the values from the query string param and the session cookie were both used during parameter binding.

Our logs showed that the requests were coming in correctly and we couldn’t reproduce the exception by recreating the request. Fortunately we had a dump of the request param values that were throwing the exceptions. We noticed the same param key was set in both ASP and MonoRail handled requests. This observation led one of my developers to speculate about cookie binding. A quick look at the Castle sources confirmed that suspicion. After a quick parameter name change, the exceptions stopped.