Tigraine

Daniel Hoelbling-Inzko talks about programming

MVC vs MonoRail – Action Methods

Many people have said nasty things about the Castle MonoRail framework since ASP.NET MVC has come out. Both serve the same purpose but both frameworks are pretty different. I did/do projects in both these days, and usually all features of A are also present in B, just slightly different.

One thing where this isn’t true is the layout of ActionMethods in MVC:

In short, MonoRail can have unlimited method overloads for ActionMethods while MVC can only overload twice (once for each HttpVerb).

What do I mean?

MVC:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [AcceptVerbs(HttpVerbs.Post)]     public ActionResult Index(int id)     {         return View();     } }

MonoRail:

public class ContactController : SmartDispatcherController
{
    public void Index()
    {
        
    }

    public void Index(int id)     {              }

    public void Index(int id, string name)     {              } }

You can see clearly, MonoRail as a framework is much smarter about what action method it will invoke. Based on what parameters you supply it will pick the best match. 
MVC will simply use reflection to invoke any method with that name that matches the HttpVerb, so once you remove the AcceptVerbs attribute MVC will break with a AmbiguousMatchException.

MVC vs MonoRail

Just to get bias out of the way: I believe MVC is technically still inferior to MonoRail but makes that up in larger community and (much) better documentation. What you pick is largely dependant on how well you know your way around missing documentation and open source code mailing lists.

To illustrate this I went to stackoverflow and compared the number of questions tagged with asp.net-mvc with those tagged castle-monorail. The results may very well speak for themselves:

image

It’s a shame I have to say. MonoRail is such a nice framework and it really does not deserve getting stomped by ASP.NET MVC. As funny as this may sound for a OSS project, currently the best way to contribute to MonoRail is to write about it and if possible improve documentation around it. I guess that says everything about the quality/maturity of the framework.

Filed under net, castle, programmierung

Bad poor man’s IoC in default MVC template

This is directly from the standard MVC template upon starting a new project:

// This constructor is used by the MVC framework to instantiate the controller using
// the default forms authentication and membership providers.

public AccountController()     : this(null, null) { }

// This constructor is not used by the MVC framework but is instead provided for ease // of unit testing this type. See the comments at the end of this file for more // information. public AccountController(IFormsAuthentication formsAuth, IMembershipService service) {     FormsAuth = formsAuth ?? new FormsAuthenticationService();     MembershipService = service ?? new AccountMembershipService(); }

I didn’t realize this is in the default template of ANY MVC install when Ayende pointed this out in his NerdDinner review yesterday. Wow, speaking of bad defaults..

If you don’t want to burden yourself with “real” IoC, at least do it right:

// This constructor is used by the MVC framework to instantiate the controller using
// the default forms authentication and membership providers.

public AccountController()             : this(new FormsAuthenticationService(), new AccountMembershipService()) { }

// This constructor is not used by the MVC framework but is instead provided for ease // of unit testing this type. See the comments at the end of this file for more // information. public AccountController(IFormsAuthentication formsAuth, IMembershipService service) {     FormsAuth = formsAuth;     MembershipService = service; }

Filed under net, programmierung

SSL Errors can indicate wrong system time

Imagine my face when I got the following screen while logging into Gmail in the morning:

image

Chrome really suggested that www.google.com has no valid SSL certificate and may be dangerous.
Also services like Windows Live Messenger and Windows Update refused to work due to broken SSL certificates.

Turns out, I accidentally set the system clock after a bios reset to 28. July 2008 instead of 2009. I guess I looked at the system time about 3 times before noticing the error :(.

Funny: The wrong year also prevented me from syncing the time with time.windows.com to get to the right one.

Filed under personal

Keeping up with Castle

Especially when trying to follow the development of a big project like Castle you can get lost quickly. There is no real “main” endpoint to refer to. Some news get out there through the development mailing list, sometimes they come through blogs and sometimes they are only present in code.

What I found useful in following the project are the following places:

  1. Castle Project aggregator – a aggregate feed of most known figures involved in the castle development process
  2. Castle Project development mailing list – The place where discussion about features and structure happens
  3. Castle Project svn log – I like to look at commits to see what’s going on
    Note: Especially with castle where the last “official” release was in 2007 it’s imo quite important to know what’s going on when you are running the trunk version.

Filed under net, castle, programmierung

Keeping up with Castle binaries through NAnt

One of the main annoyances of running from the castle trunk for me was copying new assemblies to my projects. Whenever I see something interesting pop up in the mailing list I usually run a SVN update to see what changed. While the castle build process is pretty simple at this point, picking the right assemblies and copying them to an ongoing project manually is just painful.

I did this exactly twice before I remembered the golden rule: automate!

This little NAnt target is now in charge of copying assemblies I need to my project’s lib directory:

<target name="castle-update">
<if test="${property::exists('castle-trunk-dir')}">
	
	<if test="${property::exists('skip-castle-compile') == false}">
		<echo message="Compiling castle trunk release binaries..." />
		<exec program="build.cmd" basedir="${castle-trunk-dir}" workingdir="${castle-trunk-dir}">
		</exec>
	</if>
	
	<echo message="copying castle binaries" />
	
	<copy todir="lib\castle">
		<fileset basedir="${castle-trunk-dir}\build\net-3.5\release\">
			<include name="Castle.ActiveRecord.???" />
			<include name="Castle.Components.Binder.???" />
			<include name="Castle.Components.Common.EmailSender.???" />
			<include name="Castle.Components.Common.TemplateEngine.???" />
			<include name="Castle.Components.Common.TemplateEngine.NVelocityTemplateEngine.???" />
			<include name="Castle.Components.DictionaryAdapter.???" />
			<include name="Castle.Components.Pagination.???" />
			<include name="Castle.Components.Validator.???" />
			<include name="Castle.Core.???" />
			<include name="Castle.DynamicProxy2.???" /> 
			<include name="Castle.MonoRail.ActiveRecordSupport.???" />
			<include name="Castle.MonoRail.Framework.???" />
			<include name="Castle.MonoRail.Framework.Views.NVelocity.???" />
			<include name="Castle.MonoRail.TestSupport.???" />
			<include name="Castle.Services.Logging.Log4netIntegration.???" />
			<include name="Iesi.Collections.???" />
			<include name="log4net.???" />
			<include name="*.license.txt" />
			<include name="NHibernate.ByteCode.Castle.???" />
			<include name="NHibernate.???" />
			<include name="NVelocity.???" />
		</fileset>
	</copy>
</if>
<if test="${property::exists('castle-trunk-dir') == false}">
	<fail message="Please specify the directory to castle-trunk through -D:castle-trunk-dir=<directory>" />
</if>
</target>

This little script will compile castle and then copy over all files I need to my /lib/castle folder, making a castle update as easy as writing:

build castle-update -D:castle-trunk-dir=..\open-source\castle-trunk

Make sure you have your /lib/ folder under source control in case some breaking changes come from the new castle binaries.

Filed under net, castle, programmierung

FileUpload in MonoRail

After a stressful week of non-computer related stuff eating up my time today I finally got around to continue some work on the imagineClub website.
I approached the section of file uploads and just wanted to quickly point out an excellent post by Ken Egozi about how to properly handle file uploads with MonoRail.

FileBinderAttribute to ease FileUpload in MonoRail – by Ken Egozi

It’s really nice to see that MonoRail has File upload baked directly into the framework. It’s as easy as that:

public void Upload([DataBind("Document")] Document document, HttpPostedFile uploadedFile)
{
	if (uploadedFile != null)
	{
		//TODO: Save File to Disk, Test this properly
	}
}

But what Ken addresses is a neat way to keep this testable without obscuring the controller code.

Also, apparently Ken has written his own weblog engine ontop of MonoRail and even opensourced it for the public to look at and hopefully learn something from it. It’s really great to see real application code somewhere instead of just samples and short demos. Also from what I saw in the repository it’s not too complex to make you cry and yet real enough to show you some interesting things about MonoRail.

Filed under net, castle, programmierung

Troublesome SQL Server 2008 installation

Since Visual Studio 2008 ships with a SQL Server Express 2005 installation I never really bothered to change that. All tools I work with support that and I never needed any of the 2008 specific features before.

Only, the current imagineClub Website is hosted on a SQL Server 2008 installation, so in order to access that database on my development machine I needed to install a 2008 version.
I figured it would be best to upgrade to Microsoft SQL Server 2008 Developer edition since I can get that for free through the imagineClub MSDN AA agreement so I downloaded the ISO and started the install, expecting the setup to figure out how to upgrade my current installation.

Unfortunately that is not possible. The SQL Server 2008 setup failed miserably and the setup is not automatically rolling back. That means that I ended up with a partial 2008 install and a partial 2005 install.
Most services were installed twice and neither would work.

Unfortunately the SQL Server Setup is just a collection of MSI files that get called in some weird order through the main setup routine. Therefore the errorlog of the main install just references other logfiles that should contain error-details, but skipping through an alien 30k logfile isn’t the easiest task.

I could finally complete the setup by running the uninstall on ALL things that contained SQL in their name on my machine, until only “Microsoft Sql Server 2008 (64-bit)” was left.

image

The main SQL Server 2008 entry then told me that apparently all parts of SQL Server 2008 are gone and it will remove itself from my programs list.

I then was able to re-run the standard installation and now I’m finally up and running with SQL Server 2008!

image

Apparently I was lucky to get away so easy. If the above isn’t working you could try to follow Mark Michaelis tips on how to get rid of SQl Server 2005/2008 manually.

Anyway, uninstall SQL Server 2005 Express before attempting to install a SQL Server 2008. Saves time in the long run!

Filed under programmierung

ARFetch attribute in MonoRail

MonoRail and ASP.NET MVC while being very different both almost mirror their features. Few things are impossible in one of both and the only really major difference between those two is that MonoRail comes packed with a suggested data access strategy: ActiveRecord.

This pre-packing is completely optional, it’s very easy to implement whatever data access logic you like, but if you choose ActiveRecord you’ll benefit from some nice things like the ARFetch attribute.

See this action method and judge for yourself:

public void Detail([ARFetch("Id")] NewsPost post)
{
    PropertyBag["post"] = post;
}

You just tell MonoRail through ARFetch what request-parameter is the object’s Id and it will fetch that entity from your DB and pass it into your method. It’s so simple that it’s almost tragic, yet it’s a huge time saver in most CRUD cases (edit, update and delete usually involve fetching the entity first).

Also, for a change, ARFetch is one of those few things inside MonoRail that needs zero documentation. It just works! (Besides the fact that you need to know it exists of course).

Filed under net, castle, programmierung

Windows Live Writer Plugin: Wrap code in &lt;tt&gt;

As of late I try to mark code parts inside normal text with the <tt> tags to make them stand out as code. While writing my MonoRail tutorial yesterday I got really annoyed by switching between source and normal view inside Windows Live writer to add <tt> all over the place, so I figured I’d use the WLW Plugin API to write a plugin that wraps text inside <tt>.

namespace wlwWrapIn
{
    using System;
    using System.Windows.Forms;
    using WindowsLive.Writer.Api;

    [WriterPlugin("37CB2E7F-1809-4344-9527-526768A99E9F", "WrapInTT", PublisherUrl = "http://www.tigraine.at")]     [InsertableContentSource("Wrap in <tt>", MenuText = "Wrap in <tt>", SidebarText = "Wrap in <tt>")]     public class WlwWrapIn : ContentSource     {         public override System.Windows.Forms.DialogResult CreateContent(System.Windows.Forms.IWin32Window dialogOwner, ref string content)         {             content = String.Format("<tt>{0}</tt>", content);             return DialogResult.OK;         }     } }

Oh yeah it is that simple, just reference the WindowsLive.Writer.Api class and you can write a plugin like that.

In case someone needs my <tt> wrapping plugin, you can get it here: WrapInTT.dll

Filed under net, programmierung, projects

Building a databound contact form with MonoRail &ndash; Part 1: Views and Databinding

In this tutorial we will look the steps necessary to create a form with Castle MonoRail that then gets sent off by email. It will touch FormsHelpers, DataBinding and using the EmailTemplateService to style and EmailSender to send a message.

The tutorial will probably be split into three parts:

Views and Databinding

I assume you already have a (maybe blank) MonoRail site running, if not you could check out this changeset on my sample-repository where the MonoRail sample app is still pristine.

1 – Creating the Controller

There are two components to a contact form: The form and the thanks screen.
In MVC speech that means we’ll have one Index action just serving up the view, and one Thanks action doing the email sending / heavy lifting.
Anyway the controller for now looks fairly simple:

public class ContactController : SmartDispatcherController
{
    public void Index()
    {
        
    }
}

2 – Creating the View

image The usual routine for creating MonoRail NVelocity views applies here. The \Views\<controllername>\<actionname>.vm convention dictates that our View is called “Index.vm” and placed inside the \Views\Contact\ folder

(Btw, you probably want to tell Visual Studio to open .vm files in HTML view with Rightclick .vm file –> Open With –> select HTML Editor –> Hit Set as Default)

Inside the View we need textfields for Name, Email and Subject. And of course one big textarea for the user’s text.

We all know how HTML works: we could go ahead and build a nice accessible form by putting together <input type… tags there and hand-coding everything ourselves. Or we’d just rely on the MonoRail FormsHelper to provide methods to generate the inputs for us:

<form method="post" action="$UrlHelper.For("%{action='Thanks'}")">
<fieldset>
    <legend>Contact Form</legend>
    <ol>
        <li>$FormHelper.LabelFor("FormData.Name", "Name")
        $FormHelper.TextField("FormData.Name")</li>
        <li>$FormHelper.LabelFor("FormData.Email", "Email")
        $FormHelper.TextField("FormData.Email")</li>
        <li>$FormHelper.LabelFor("FormData.Subject", "Subject")
        $FormHelper.TextField("FormData.Subject")</li>
        <li>$FormHelper.LabelFor("FormData.Text", "Message")
        $FormHelper.TextArea("FormData.Text", "%{rows='14', cols='0'}")</li>
    </ol>
    <input type="submit" id="submit" value="Send" />
</fieldset>
</form>

Note the $FormHelper.TextField(“FormData.Name”)call that results in a <input type="text" id="FormData_Name" name="FormData.Name" value="" />. One nice side-effect of using this helper is that it will look at the current request parameters and if a FormData.Email value is set display it as the textfields value.

Also Interesting here is the syntax NVelocity uses to specify Dictionary data inside the view: “%{key=’value’}” specifies a IDictionary that gets passed off to our helpers.

3 – Creating the DTO

A contact-request is a message, so I like to have a data-object to represent that message during processing. This also makes it easier for us to retrieve the inputs sent from the Form (more on that later).
So we create a class called ContactRequest in the Models\ folder that can easily hold our form data:

namespace MonoRail.ContactForm.Models
{
    public class ContactRequest
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public string Subject { get; set; }
        public string Text { get; set; }
    }
}

4 – Databinding the DTO to our Form

You may have noticed that I named all TextFields in step 2 FormData.something where something corresponds to the fields inside the DTO from step 3. FormData is just a arbitrary string to prefix all of my inputs, where the latter will be used by MonoRail’s DataBinder to map the values onto my DTO.


We just need to instruct MonoRail on our action method to bind to all Query parameters starting with FormData and stuff them into our ContactRequest object. Our controller now looks like this:

public class ContactController : SmartDispatcherController
{
    public void Index()
    {
        
    }

    public void Thanks([DataBind("FormData")] ContactRequest request)     {              } }

If we debug into this action you can see that the request parameter gets filled by MonoRail with the values from the Query:

image

Since we now have a Thanks action on our Controller we also need to create a Thanks.vm view inside our Views\Contact\ folder. A blank one will do for this tutorial.

Now that we have the form up and bound our DTO to it, we’ll continue in our next tutorial step with rendering and email and sending it.

Filed under net, castle, programmierung

My Photography business

Projects

dynamic css for .NET

Archives

more