I’ve had the good fortune to have the opportunity to use Castle MonoRail on a project I’m currently working on which required certain aspects of the system to have a web interface. I’ve been using other bits of the Castle framework, like ActiveRecord, Windsor and Aspect# for quite a while now, but since I’m not often involved in developing web applications (read: actively avoid it) I’d had little incentive to play with MonoRail at all. In fact, it was a brief dalliance with Ruby On Rails and a sudden need to delve once again into the realm of web development that lead me back to it, intrigued by the development model and philosophy that the two frameworks are based on. I won't launch into a song and dance about the virtues of RoR, and by extension, MonoRail; unless you've been living under a rock somewhere you've no doubt seen a hundred pundits heaping praise on it.
What has been particularly interesting to me is the way the various aspects of the Castle Project come together so neatly in MonoRail, almost to the point where one could be forgiven for thinking that it may have been Hammet & Co’s grand design all along. (Indeed, it may well have been, I have no idea.)
I must report that my interest in and subsequent use of MonoRail has had the particular benefit of making me not utterly hate web development for the time being, although how long this burst of enthusiasm will last is anyone’s guess. I’ve never felt particularly comfortable with WebForms development for no reason I can adequately define, and so the RoR/ActionPack approach has been a breath of fresh air, with MonoRail allowing me to implement the concepts in C#, which was a prerequisite for this project.
I thought that since the buzz around Castle and MonoRail is growing it might be worthwhile to post a few tidbits of my ongoing MonoRail adventure, and perhaps help some other poor soul along a road which can be confusing and treacherous at times. I'm not going to go into too much background detail around MonoRail and its functionality as I go, since this is not intended to be a beginner's primer - if you're looking for something along those lines there are a lot of good articles and quite an abundance of sample code, although some of it takes some searching to find. I'll simply concentrate on posting whatever interesting oddities I happen upon, as well as any useful links I find.
Gotcha #1: Identifying your remote forms
MonoRail employs the very nifty concept of Helpers, which allow to manipulate your templates in any number of useful ways. Despite offering you the option to build your own custom helpers, it comes with a bunch of built-in goodies too, one of which is the AjaxHelper, which makes it really easy (eventually) to add some cool Ajax capability to your pages. For a total web/Ajax n00b like me, its been a godsend.
I did run into one problem with it though. I was attempting to do some input validation using another helper, the FormHelper, which aside from outputting all the necessary form and input html tag stuff you need, provides you with a bunch of validation scripts and plugs in the JavaScript for you. Kinda like this:
1: $Form.FormTag("page2.rails", "%{}")
2:
3: <!-- some form stuff -->
4:
5: $Form.EndFormTag()
Only one problem though.. its only when you call EndFormTag() that the helper puts in the JavaScript to trigger the validation. And when you try this:
1: $AjaxHelper.BuildFormRemoteTag("page2.rails", "%{}")
2:
3: <!-- some form stuff -->
4:
5: $Form.EndFormTag()
...the helper doesn't include the JavaScript you need, I'm guessing because you didn't start the form with the same helper (yes, I know the source code is available and I don't need to guess, I have it checked out of Subversion but I didn't feel like digging into it at the time). Anyway, the fix seemed easy enough - get the JavaScript that it outputs and slap it in myself, closing the form tag without the use of a helper. Only problem was, while the FormHelper assumed a form id of "form1" if you didn't provide one when building the HTML tag, the AjaxHelper was less forgiving. The answer seemed obvious enough since, the method takes a hash table of tag options:
1: $AjaxHelper.BuildFormRemoteTag("page2.rails", "%{id='form1'}")
Rather frustratingly this did nothing to alleviate my pain, and so I was finally forced to delve into the source. Turns out that, mysteriously, and flying in the face of the way the framework works everywhere else, you need to use the specific string "formId", which the helper will then infer as the tag attribute "id".
1: $AjaxHelper.BuildFormRemoteTag("page2.rails", "%{formId='form1'}")
Perhaps not the most interesting first post on MonoRail, but hopefully it will save someone else some pain somewhere along the way.