Action behavior using ASP.NET MVC and MvcContrib

This post is a quick rundown of action method behaviors.  This will be halfway obsolete with the next MVC drop on codeplex, but here goes:

You can download MvcContrib from http://mvccontrib.org.  The convention controller is there.  The ConventionController takes away nothing from System.Web.Mvc.Controller, but it adds some useful things on top.  My example controllers inherit from ConventionController.

First, To get an action method to fire and run, just make it public.  Now it’s web callable:

public class TwitterController : ConventionController
{
    public void SaveTweet(string tweet)
    {
        //integrate with twitter to do cool stuff.
        Response.Write("Wrote: " + tweet);
    }
}

If you run the above action with the default routes, you’ll get the error:

A public action method named ‘Index’ could not be found on the controller.

To fix that, we can add MvcContrib.Attributes.DefaultActionAttribute and to to the url:  http://localhost:1308/twitter?tweet=howdy

 

[DefaultAction]
public void SaveTweet(string tweet)
{
    //integrate with twitter to do cool stuff.
    Response.Write("Wrote: " + tweet);
}

And the output is:

Wrote: howdy

 

Now, what if I didn’t want the SaveTweet method to be web-callable.  Perhaps it’s a public method on a controller that isn’t an action.  I can added System.Web.Mvc.NonActionAttribute, and I’ll navigate to http://localhost:1308/twitter/savetweet?tweet=howdy.

 

[NonAction]

/twitter/savetweet?tweet=howdy.

{
    //integrate with twitter to do cool stuff.
    Response.Write("Wrote: " + tweet);
}

Then I get the following error because now SaveTweet is not an action method:

A public action method named ‘savetweet’ could not be found on the controller.

 

Now, finally, if we look at the method name, we can see that SaveTweet(string tweet) is a non-repeatable action.  It has side effects.  It’s pushing a tweet to twitter.  We probably don’t want that to happen with a GET.  In other words, we don’t want the mere act of navigating to /twitter/savetweet?tweet=howdy to cause a backend change in the system.  Because of this, it’s reasonable to restrict this action to POSTs only.  We can do that by using the MvcContrib.Attributes.PostOnlyAttribute:

 

[PostOnly]
public void SaveTweet(string tweet)
{
    //integrate with twitter to do cool stuff.
    Response.Write("Wrote: " + tweet);
}

 

If we attempt to run this with a GET, we’ll see the following error:

Action ‘SaveTweet’ can only be accessed using an HTTP Post.

 

I’ve given a quick rundown of different ways to use action methods.  Note that the ASP.NET MVC Framework is still in flux, and things will still change dramatically.  I, and others, are expressing our constantly evolving understanding of how to use the ASP.NET MVC Framework as time goes on.  This understanding is expressed in the MvcContrib and CodeCampServer.  You can follow my understanding process on my feed at http://feeds.feedburner.com/jeffreypalermo.

Also follow Phil Haack, who is a PM steering the evolution of the framework.