UPDATE: Much of this post is out-of-date with the latest versions of
MVC. We long sinced removed the
Note: If you hate reading and just want the code, it is at the bottom.
Eons ago, I was a youngster living in
watching my Saturday morning cartoons when my dad walked in bearing
freshly made taquitos and a small cup of green stuff. The taquitos
looked delicious, but I was appalled at the green stuff.
Was this some kind of joke? My dad wanted me to simply just taste it
but I refused because I absolutely knew it would suck just by looking at
it. The green stuff, of course, was guacamole, which I love by the
With all the code samples and blog posts published about the ASP.NET MVC
Framework, there’s been some debate about the big picture stuff.
- Should I be looking to migrate to this? (Depends)
- Will this replace Web Forms? (NO!)
- Is this feature even necessary? (I sure think so!)
Interestingly enough, the most passionate debate I’ve seen is not around
these big picture questions, but is centered around very specific
detailed design decisions. After all, we are software developers, and if
there’s one thing software developers love to do, it’s debate the design
and architecture of code.
I’m no exception to this rule and admit I rather enjoy it, sometimes to
the point of absurdity and pointlessness. At the end of the day,
however, the framework developer has to make a decision and move forward
so he or she can go home. These choices will never make everyone happy
because there is no such thing as a perfect
that satisfies everyone.
That doesn’t mean we give up trying though!
Hopefully the quality of feedback the framework designer receives pushes
that designer to reevaluate assumptions and either reinforces the
decision, or provides insight for an even better decision.
One design decision in particular that seems to have drawn somewhat
disproportionate amount of attention is the decision to require a
[ControllerAction] attribute on public methods within a controller
class that are meant to be a web visible action. There’s been much
discussion in various mailing lists and in some blog posts before the
CTP has been released.
This post is not going to rehash these concerns nor address these
concerns. If I think it would help, perhaps I will have a follow-up post
in which I explain some of the reasoning behind this decision. This
would give those who feel all that strongly about this a chance to
make a well-reasoned point by point refutation should they wish.
I worry about focusing too much on this one issue. I don’t want it to
become such a hang up that it disproportionately dominates discussion
and feedback at the expense of gathering valuable feedback on other
areas of the framework. There is much more to the framework than this
At the same time, I do understand this issue is about more than a single
attribute. It’s about applying a design philosophy centered around
convention over configurationand where it works well and where it
Like guacamole, I hope that critics of this particular issue don’t judge
it by sight alone and give it a real honest try. See if it makes as big
a difference as you think. Maybe it does. Maybe it doesn’t. At least
you’ve tasted it. Feedback based on trying it out for a while is
more valuable and potent than feedback based on just on seeing sample
Please understand that I’m not dismissing feedback based on what you
have seen. It certainly is valuable and much of it has been
incorporated and discussed in our design meetings. Some of it has led to
changes. All I am saying is that as valuable as that feedback is,
feedback based on usage is even more valuable.
The Convention Controller
However, if you still hate it, I have a little workaround for you :).
I’ve written a custom controller base class that allows for a more
“convention over configuration” approach to building your controllers
By inheriting from this controller instead of the vanilla
class, you no longer need to add the [ControllerAction] attribute to
every public method. You also don’t need to call
RenderView if you
name your view the same name as the action. Of course this means you
cannot use strongly typed views and must use the
ViewData property bag
to pass data to the view.
So instead of writing your controller like this:
public class HomeController : Controller
public void Index()
//Your action logic
Using my class you could write it like this
public class HomeController : ConventionController
public void Index()
//Your action logic
The key point in posting this code is to demonstrate how easy it is to
override the behavior we bake in with something more to your liking.
When you look at the code, you will see it wasn’t rocket science to do
what I did. Extending the framework is quite easy.
We may not provide the exact out of box experience that you want, but
we do try and give you the tools to control your own destiny with this
framework and provide you with the power of choice.
I will look into adding this to the MVC Contrib
project started by
some community members. In the meanwhile, if you like this approach or
style of building controllers, you can either add the
ConventionController.cs class to your own project or compile it into a
separate assembly and drop it into your own projects.
To get to this class, download the example