Grouping Controllers with ASP.NET MVC

UPDATE: I updated the prototype to work against the ASP.NET MVC RC

A question that often comes up is how do you group controllers when building a large application with ASP.NET MVC. Often, the question is phrased as whether or not ASP.NET MVC supports “Areas”, a feature of Monorail. According to the Monorail documentation,

MonoRail supports the concept of areas, which are logical groups of controllers. All controllers belong to an area. The default area is an empty (unnamed) one

While there’s no out of the box support for this in ASP.NET MVC, the extensibility model allows building something pretty close. I thought I would spend a few hours one morning trying to come up with a prototype of this. The funny part with things like this is that I’ve probably spent as much time writing this blog post as I did working on the prototype, if not more!

The scenario that areas address is being able to partition your application into discrete areas of functionality. It helps make managing a large application more manageable and allows for creating distinct applets that you can drop into an application.

For example, suppose I want to drop in a blogs subfolder, complete with its own controllers and views, along with a forums subfolder with its own controllers and views, into a default project. The end result might look like the following screenshot (area folders highlighted).

areas-folder-structure

Notice that these folders have their own Views, Content, and Controllers directories. This is slightly similar to a solution proposed by Steve Sanderson, but he ran into a few problems we’d like to resolve.

  • URL generation doesn’t take namespaces into consideration when generating a URL. We want to be able to easily generate URLs to other areas.
  • When you are within one area, and you call Html.ActionLink to link to another action in the same area, you’d like to not have to specify the area name. You’d also like to not be forced to specify a route name.
  • You still want to be able to link to another area by specifying the area name. And, you want to be able to have controllers of the same name within the same area.
  • You also want to be able to link to the “root” area, aka the default HomeController that comes with the project template that is not located in an area.

The prototype I put together resolves these problems by adopting and enforcing a few constraints when it comes to areas.

  • The area portion comes first in the URL.
  • Controller namespaces must have a specific format that includes the area name in the namespace.
  • The root controllers that are not in any area have a default area name of “root”.
  • When resolving a View/Partial View for a controller within an area, we search in the area’s Views folder first. If not found there, we then look in the root Views folder.

Overridable Templating

This last point bears a bit of elaboration. It is a technique that came about from some experimentation I did on a potential new way of skinning for Subtext.

In the Blogs area, I have a partial view called LoginUserControl.ascx. In the Forums area, I don’t have this partial view. Thus when you go to the Forums area, it falls back to the root Views directory in order to render this partial view. But in the Blogs area, it uses the one specified in the area. This is a convenient way of implementing overridable templating and is reminiscent of ASP.NET Dynamic Data.

If you run the sample, you’ll see what I mean. When you hit the Blogs area, the login link is replaced by some text saying “Blogs don’t need no stinking login”, but the Forums area still has the login link.

Note that all of these conventions are specifically for this prototype. It would be very easy to relax these constraints to fit you’re own way of doing things. I just wanted to show how this could be done using the current ASP.NET MVC bits.

Registering Routes

The first thing we do is call two new extension methods I wrote to register routes for the areas. This call is made in the RegisterRoutes method in Global.asax.cs.

routes.MapAreas("{controller}/{action}/{id}", 
    "AreasDemo", 
    new[]{ "Blogs", "Forums" });

routes.MapRootArea("{controller}/{action}/{id}", 
    "AreasDemo", 
    new { controller = "Home", action = "Index", id = "" });

The first argument to the MapAreas method is the Routing URL pattern you know and love. We will prepend an area to that URL. The second argument is a root namespace. By convention, we will append “.Areas.AreaName.Controllers” to the provided root namespace and use that as the namespace in which we lookup controller types.

For example, suppose you have a root namespace of MyRootNamespace. If you have a HomeController class within the Blogs area, its full type name would need to be

MyRootNamespace.Areas.Blogs.Controllers.HomeController.

Again, this is a convention I made up, it could be easily changed. The nice thing about following this convention is you don’t really have to think about namespaces if you follow the directory structure I outlined. You just focus on your areas.

The last argument to the method is a string array of the “areas” in your application. Perhaps I could derive this automatically by examining the file structure, but I put together this prototype in the morning and didn’t think of that till I was writing this blog post. ;)

The second method, MapRootArea, is exactly the same as MapRoute, except it adds a default of area = “root” to the defaults dictionary.

Registering the ViewEngine

I also wrote a very simple custom view engine that knows how to look in the Areas folder first, before looking in the root Views folder when searching for a view or partial view.

I wrote this in such a way that it replaces the default view engine. To make this switch, I added the following in Global.asax.cs in the Application_Start method.

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new AreaViewEngine());

The code for the AreaViewEngine is fairly simple. It inherits from WebFormViewEngine and looks in the appropriate Areas first for a given view or partial view before looking in the default location. The way I accomplished this was by adding some catch-all location formats such as ~/{0}.aspx and formatted those myself in the code.

If that last sentence meant nothing to you, don’t worry. It’s an implementation detail of the view engine.

Linking to Areas

In the root view, I have the following markup to link to the HomeController and Index action of each area.

<%= Html.ActionLink("Blog Home", "Index", new { area="Blogs" } )%>
<%= Html.ActionLink("Forums Home", "Index", new { area="Forums" } )%>

However, within an area, I don’t have to specify the area when linking to another action within the same area. It chooses the current area by default. For example, here’s the code to render a link to the Blogs area’s Posts action.

<%= Html.ActionLink("Blogs Posts", "Posts") %>

That’s no different than if you weren’t doing areas. Of course, if I want to link to the forums area, I need to specify that. Also, if I want to link to an action in the root, I need to specify that as well.

<%= Html.ActionLink("Forums", "Index", "new {area="forums"}") %>
<%= Html.ActionLink("Root Home", "Index", "new {area="root"}") %>

As you click around in the sample, you’ll notice that I changed the background color when in a different area to highlight that fact.

Next Step, Nested Areas

One thing my prototype doesn’t address are nested areas. This is something I’ll try to tackle next. I’m going to see if I can clean up the implementation later and possibly get them into the MVC Futures project. This is just some early playing around I did on my own so do let me know if you have better ideas for improving this.

Download the Sample

Technorati Tags: ,

What others have said

Requesting Gravatar... Elijah Manor Nov 04, 2008 1:12 PM
# re: Grouping Controllers with ASP.NET MVC
Very nice... I look forward to using this approach.

Is there anything about supporting sub-controllers in the works too!?!
Requesting Gravatar... Steve Mason Nov 04, 2008 1:34 PM
# re: Grouping Controllers with ASP.NET MVC
Looks great, though does this support the use of the Html.ActionLink<T>(Expression) extensions method in your views?
Requesting Gravatar... haacked Nov 04, 2008 2:06 PM
# re: Grouping Controllers with ASP.NET MVC
@Elijah we have an old prototype, but it needs to be updated.

@Steve I doubt it. I didn't revisit those methods. They'd have to know how to convert the full type name of the controller into an area string in order to work. It's doable by following the conventions. If this work makes it into the futures, I can look into that.
Requesting Gravatar... Andrew Rimmer Nov 04, 2008 2:19 PM
# re: Grouping Controllers with ASP.NET MVC
Excellent work!

I think the method of building a website out of seperate applications (modules) really needs to be a strong convention. I really enjoy building websites with ASP.NET MVC in comparison to WebForms.

However, I recently tried Django to build a couple of apps, so that I could feed my experience of using a more mature mvc-like app into my asp.net mvc projects. What came across was that you could build a website out of multiple applications very easily.

Building a website out of multiple apps in ASP.NET MVC has been a bit of a chore so far. The extensibility points are there, so if I wanted to do my a website, and roll my own blog, forums it would be easy enough. However what we really need, is to be able to drop in applications that have already been developed.

So, if I want to develop a social community website I would drop in open source components/apps/areas like SubText MVC, Forums MVC. I don't see an easy way of doing this right now, although I know its early days.
Requesting Gravatar... Jeff Sheldon Nov 04, 2008 2:32 PM
# re: Grouping Controllers with ASP.NET MVC
Phil, you're awesome!
I was looking at this exact issue this afternoon and was contemplating how I'd tackle it on my drive home.
Requesting Gravatar... Tony Bunce Nov 04, 2008 3:13 PM
# re: Grouping Controllers with ASP.NET MVC
Looks great Phil. I was just looking into this a few hours ago wondering if it was possible.

This should make it much easier to migrate "class" webform apps to MVC.

I also want to second Andrew's idea of making it easy to combine multiple MVC applications to make a single site. In addition to the Blog/Forum situation I think it would be a good way for commercial web apps to offer plug ins or modules.
Requesting Gravatar... Justice~! Nov 04, 2008 4:14 PM
# re: Grouping Controllers with ASP.NET MVC
We did something similar to this on my current contract re: overridable views and areas, as our application essentially needs to "reinvent" parts itself each year (different set of business rules, different potential flow, different additions/subtractions to or from the form elements).

To Steve Mason: I have it working with the strongly typed Actions so if you want to chat further about it just drop me a twitter or something.
Requesting Gravatar... haacked Nov 04, 2008 5:01 PM
# re: Grouping Controllers with ASP.NET MVC
I really like the idea of additively composing a single app from multiple apps. That's something we've talked about a lot internally and I'll try to continue developing this prototype towards that end.
Requesting Gravatar... Steve Nov 04, 2008 5:51 PM
# re: Grouping Controllers with ASP.NET MVC
Excellent, thanks Phil!
Requesting Gravatar... Ervin Ter Nov 04, 2008 8:15 PM
# re: Grouping Controllers with ASP.NET MVC
Thanks for sharing this. This is better way to organized into more modular way.
Requesting Gravatar... Torkel Ödegaard Nov 04, 2008 11:01 PM
# re: Grouping Controllers with ASP.NET MVC
Nice solution. I like the convention based approach :)
Requesting Gravatar... Shiju Varghese Nov 04, 2008 11:22 PM
# re: Grouping Controllers with ASP.NET MVC
Phil,

Great work. Thanks for sharing this.
Requesting Gravatar... Crocod Nov 05, 2008 12:24 AM
# re: Grouping Controllers with ASP.NET MVC
Thanks for sharing.
How does it relate to Subcontroller's idea?
Requesting Gravatar... Donovan Hide Nov 05, 2008 3:07 AM
# re: Grouping Controllers with ASP.NET MVC
Hi,

it is good to see that the direction of writing reusuable "sub-applications" is being followed. The pluggability and extensibility of applications within a project is the one of the key selling points of Django as can be seen from the thriving collection of Google Hosted Projects. http://code.google.com/p/django-tagging/ is probably the most-used of them all.

It would be interesting to know if you are examining an install of Django for inspiration with your work. I'm working on an MVC app right now, and severely missing the reusable Form abstraction that exists in Django. You are some way there with the model binding, but there needs to be better support for iterating over fields in a form, for instance. I'm writing a lot of repetitive code at the moment and the HTML Form Helpers are more of a burden than a help.

Remember imitation is the highest "form" of flattery!
Requesting Gravatar... Steve Sanderson Nov 05, 2008 5:50 AM
# re: Grouping Controllers with ASP.NET MVC
Nice one! This is the neatest solution to app areas that I've seen so far in ASP.NET MVC.

It gave me a few ideas about how I'd tweak this design, which I've written up at blog.codeville.net/.../app-areas-in-aspnet-mvc-...

@People posting about subcontrollers: It's not really related. The name "subcontrollers" tends to make everyone jump to a wide range of false assumptions about what that mechanism is about. Maybe a more specific name is needed.
Requesting Gravatar... Steve Nov 05, 2008 6:34 AM
# re: Grouping Controllers with ASP.NET MVC
A co-worker and I were talking and wondered about the following:

Is it possible to change the formatting of the URL for areas to something like:

http://localhost/{area}/{controller}/{action}

Where the area comes before the controller?
Requesting Gravatar... Mike Nov 05, 2008 7:43 AM
# re: Grouping Controllers with ASP.NET MVC
Hi,

I prefer to have "areas" in the controllers and views folder, I think it's more beautiful instead of have a folder called areas with the tree?

Example there admin is the "area":
/Controllers/Admin/UsersController.cs
/Views/Admin/Users/Index.aspx
/Views/Admin/Users/*.aspx
Requesting Gravatar... haacked Nov 05, 2008 8:17 AM
# re: Grouping Controllers with ASP.NET MVC
@Steve in my prototype, the area does come before the controller. But you can change it in any way you like.
Requesting Gravatar... justin Nov 05, 2008 4:17 PM
# re: Grouping Controllers with ASP.NET MVC
A month or two ago I had created a view engine that would render embedded views from an assembly. You could override the view by placing the same folder/viewname in the main projects (root) view. I didn't get very far on it as you would need to write some HtmlHelpers to get embedded javascript/css to override properly, and I got really busy with work. That said I would _love_ it if asp.net mvc supported this out of the box. It would potentially create an entire community of premade plugin websites which are easy to customize.
Requesting Gravatar... dmitry Nov 05, 2008 11:43 PM
# re: Grouping Controllers with ASP.NET MVC
Areas are very usefull
Requesting Gravatar... Jayson Nov 06, 2008 4:33 AM
# re: Grouping Controllers with ASP.NET MVC
Phil,
This is something that I've been thinking of a way to do.

One hurdle that I have in mind when I think of extensibility is referencing master pages from an outside assembly... we all want the pages to inherit from the same layout, right?

So for example, if i wanted to add "forums" functionality into my "base" mvc site, i would just drop the forums.dll into the bin, and configure the site to know about it. All views and controllers are within the forums assembly but the views would somehow inherit from the master page that the "base" site is using.

Is this something that is possible, now?
Requesting Gravatar... sliderhouserules Nov 06, 2008 11:38 PM
# re: Grouping Controllers with ASP.NET MVC
This is something I was working through almost a year ago...

forums.asp.net/p/1213639/2146611.aspx#2146611
Requesting Gravatar... sliderhouserules Nov 06, 2008 11:42 PM
# re: Grouping Controllers with ASP.NET MVC
Oops, meant to include this one...

http://forums.asp.net/t/1206611.aspx

I think it's ironic that your examples continue to be "blog engines".

Not hatin', just sayin'!
Requesting Gravatar... Kyle LeNeau Nov 07, 2008 9:55 AM
# re: Grouping Controllers with ASP.NET MVC
Nice post Phil. This is something I have been interested in for awhile and happened to stumble upon it thanks to ScottGu's Blog. What is the likely hood and/or possibility of making these "Areas/Modules" bin deploy-able? I would think that you would have to use a compilable views and a view engine like Spark. This would seem to make the inclusion of "Areas/Modules" extremely easy.
Requesting Gravatar... Tommy Nov 08, 2008 4:24 AM
# re: Grouping Controllers with ASP.NET MVC
Thank for this great post Phil. One question. Can I still map routes in Global.asax? Like:

routes.MapRoute(
"Kontrakt-Details",
"Kontrakt/{kontraktId}",
new { controller = "Kontrakt", action = "Details" }
);

This controller is located in the root namespace. Should I point it to the namespace or what? And how?
Requesting Gravatar... Andrea Balducci Nov 12, 2008 2:03 PM
# re: Grouping Controllers with ASP.NET MVC
I did it in an ASP.Net Framework i'm writing in my spare time.
You can create several different applications each one deployed in a set of custom assemblies (xcopy deployment). Every assembly can implemente one or more application ad every application can add new routes. By now is much more a proof of concept but it works since Asp.Net preview 3.
I plan to release some "real" framework (maybe with some help) in Q1 2009.
You can grab some sources from http://code.google.com/p/ecosystem15/
Requesting Gravatar... Andrea Balducci Nov 12, 2008 11:20 PM
# re: Grouping Controllers with ASP.NET MVC
I forgot to say that the whole app is compiled (static resources, scripts, views, controllers, masterpages) and deployed as embedded resources. By now i've implemented a virtualpathprovider to mix filesystem and embedded resources, so you can easily create a portal just mixing the apps you want to deploy from an application library (or in the future from an application store :)
Requesting Gravatar... tc Nov 13, 2008 11:34 AM
# re: Grouping Controllers with ASP.NET MVC
Any chance of a VB version?
Requesting Gravatar... mikenz Nov 13, 2008 11:47 PM
# re: Grouping Controllers with ASP.NET MVC
I think this would be a very useful feature to have built in to the MVC framework. I am quite surprised it wasn't already included.
Requesting Gravatar... ucin Nov 15, 2008 10:02 PM
# re: Grouping Controllers with ASP.NET MVC
I try your demo and add some parameter to controller action, but when I request the url such as http://127.0.0.1/admin/security/users/phill (phill is {id}), I always get the parameter value null.
Can give you some explanation..? while http://127.0.0.1/admin/security/users get user list (as expected),

And how this effect the action attribute such AcceptVerbs?

Thanks,

Ucin Shihab
Requesting Gravatar... Neil Nov 19, 2008 12:43 PM
# re: Grouping Controllers with ASP.NET MVC
Hi Phil,

Just a quick question as to how this effects deployment on iis6 and the .mvc routes?

Thanks

Neil
Requesting Gravatar... Dave Dec 05, 2008 11:24 AM
# re: Grouping Controllers with ASP.NET MVC
Very cool, but the lambda expressions really drive me nuts!
Requesting Gravatar... Dave Dec 05, 2008 1:27 PM
# re: Grouping Controllers with ASP.NET MVC
Is there a reason that the Views namespace is like this:
namespace AreasDemo.Views.Forums.Home

But the controllers is like this:
namespace AreasDemo.Areas.Forums.Controllers

Shouldn't the views namespace be like this:
namespace AreasDemo.Areas.Forums.Views.Home
Requesting Gravatar... haacked Dec 05, 2008 4:03 PM
# re: Grouping Controllers with ASP.NET MVC
It was just the way I prototyped it. Nothing intentional.
Requesting Gravatar... Amin Dec 08, 2008 2:37 AM
# re: Grouping Controllers with ASP.NET MVC
gr88888!
This is what I was looking for in MVC

Thanks phil
Requesting Gravatar... Kosmo Dec 19, 2008 1:17 PM
# re: Grouping Controllers with ASP.NET MVC
Any idea why my areas work when running from Visual Studio by pressing F5? The site comes up as http://localhost:1134. The root area shows and my link to my areas work also.

However, if I go directly to http://localhost/mysite, the root area comes up but I am unable able to pull up my other areas under the Areas folder.

Kosmo
Requesting Gravatar... John Morales Dec 24, 2008 6:48 AM
# re: Grouping Controllers with ASP.NET MVC
This really should be out of the box...not having support for multi level site organization is a pretty big drawback.
Requesting Gravatar... Jeroen Landheer Jan 04, 2009 2:23 AM
# re: Grouping Controllers with ASP.NET MVC
Hi Phil.

I've used your sample, but what I noticed is that views and controllers in the "root" area can be used in any other area. For example, if the root area contains a "Document" controller, and I have a area "Customer", you can either navigate to /Document/SomeAction or /Customer/Document/SomeAction, while the Customer area does not have a DocumentController class.

I've trying to prevent this by adding some constraints to the root area, but I haven't found a way to prevent this behaviour. Any ideas?
Requesting Gravatar... Ronald Rogers Jan 08, 2009 6:11 AM
# re: Grouping Controllers with ASP.NET MVC
For some reason I thought that by "areas" you meant portions of the screen. My experience to web development is limited to ASP.NET.

So I wander off-topic in wonder whether a document can be portioned out to be handled by different controllers -- some thing like content areas that could each be individually routed to...?
Requesting Gravatar... STGF Jan 16, 2009 12:17 PM
# re: Grouping Controllers with ASP.NET MVC
I tried implementing Phil's Areas Demo in my project haacked.com/.../areas-in-aspnetmvc.aspx.
I appended the Areas/Blog structure in my existing MVC project and I get the following error in my project.

The controller name 'Home' is ambiguous between the following types:
WebMVC.Controllers.HomeController
WebMVC.Areas.Blogs.Controllers.HomeController


this is how my global.asax looks.

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapAreas("{controller}/{action}/{id}",
"WebMVC.Areas.Blogs",
new[] { "Blogs", "Forums" });

routes.MapRootArea("{controller}/{action}/{id}",
"WebMVC",
new { controller = "Home", action = "Index", id = "" });

//routes.MapRoute(
// "Default", // Route name
// "{controller}/{action}/{id}",// URL with parameters
// new { controller = "Home", action = "Index", id = "" }
// // Parameter defaults
//);

}

protected void Application_Start()
{
String assemblyName = Assembly.GetExecutingAssembly().CodeBase;
String path = new Uri(assemblyName).LocalPath;
Directory.SetCurrentDirectory(Path.GetDirectoryName(path));
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new AreaViewEngine());
RegisterRoutes(RouteTable.Routes);
// RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);

}

If I remove the /Areas/Blogs from routes.MapAreas , it looks at the Index of the root.
Requesting Gravatar... RAS Jan 28, 2009 2:06 PM
# re: Grouping Controllers with ASP.NET MVC
Hi Phil,
Is there any workaround so we can make the new "scaffolding" features in RC1 work with areas?

Thank you,
Julian
Requesting Gravatar... Joe Jan 30, 2009 8:45 AM
# re: Grouping Controllers with ASP.NET MVC
Hi Phil,
I got the new RC1 assemblies and applied them in my project adn updated the code to handle the extra "useCache" parameter in hte overrides of FindView and FindPartialView.

It seems however that the viewengine is not being utilized. I still have the ViewEngines.Engines.Clear and adding a new instance of AreaViewEngine in the Application_Start, but the methods FindView and FindPartialView are not getting called.

Any ideas on how to get areas working again with RC1?

Thanks,
Joe
Requesting Gravatar... Ron Feb 09, 2009 8:35 AM
# re: Grouping Controllers with ASP.NET MVC
The controller grouping you came up with has certainly fit into the size of the project I'm working on. There are distinct areas of concern that are best broken up this way, and it's been working great.
I managed fix the AreaViewEnging issues raised in the upgrade to the Release Candidate, but I would like to use the RC feature of no code-behind files.
If I run without a code-behind, the base.FindView method returns a null reference exception.
Here's the aspx delaration I'm using. Any pointers would be appreciated.

<%@ Page Title="" Language="C#" MasterPageFile="~/Areas/AdSales/Views/Shared/AdSales.Master" Inherits="System.Web.Mvc.ViewPage<Media>" %>

Thanks in advance.
Ron
Requesting Gravatar... Mike Feb 10, 2009 1:08 AM
# re: Grouping Controllers with ASP.NET MVC
Phil, did you ever get this developed further? Right now I'm looking at several separate MVC web apps in my solution, but sharing masterpages and css across projects is a real pain. (I do it with a Subversion trick.) I think areas and nested areas are the best way to do what I want. Thanks!
Requesting Gravatar... Ron Feb 13, 2009 9:10 AM
# re: Grouping Controllers with ASP.NET MVC
Turns out my issue was only with strongly typed views. I finally found the error, with a little hint from here.
With the RC release, there is some new settings in the web.config file under /Views. If you copy that file under the /Areas/Area/Views folder, then the strongly typed views with no code behind works perfectly.

Good luck!
Requesting Gravatar... Todd Feb 19, 2009 12:42 PM
# re: Grouping Controllers with ASP.NET MVC
One of the first things I wanted to do with my MVC project was add sub-folders to the controllers and views folders!
I modified your approach a bit so that I could have subdirs without the Areas top-level dir - I think it is a cleaner approach for most people. The Areas approach prob. should be handled with external modules.
Thanks for the great article!
Requesting Gravatar... Todd Feb 23, 2009 3:47 PM
# MVC, Unity and Modularity
Further to my last post:

Since I believe that eventually (VS2010) we will see ASP.NET MVC, Unity and CAB (Prism for ASP.NET MVC) come together, I took the code bits and put them together myself.
This allows me to xcopy modules (MVC applications) to a specific area in the host MVC application (Modules subdir). The Prism modularity code then allows the modules to be loaded at start-up.
With a bit of tweaking to Phil's code (module initialization), I now have a great composite application platform for my web designs.
Requesting Gravatar... Mitch Mar 12, 2009 4:24 PM
# re: Grouping Controllers with ASP.NET MVC
We're using Phil's area code (and are liking it), but prefer the typed ActionLink methods from the Futures project, so here's a quick couple of extension methods to use if you're like me and don't like using strings so much to allow easier refactoring:

public static string ActionLinkArea<TController>(this HtmlHelper helper, Expression<Action<TController>> action, string linkText, object routeValues) where TController : Controller
{
return helper.ActionLinkArea(action, linkText, routeValues, null);
}

public static string ActionLinkArea<TController>(this HtmlHelper helper, Expression<Action<TController>> action, string linkText, object routeValues, object htmlAttributes) where TController : Controller
{
var routingValues = ExpressionHelper.GetRouteValuesFromExpression(action);
return helper.ActionLink(linkText, routingValues["action"].ToString(), routingValues["controller"].ToString(), routeValues, htmlAttributes);
}

And example usages are:

Html.ActionLinkArea<Web.Controllers.HomeController>(p => p.Index(), "home page", new {area="root"})

Html.ActionLinkArea<Ave.Web.Controllers.HomeController>(p => p.SignUp(), "Sign Up", new {area="root"}, new {behavior="dialog"})
Requesting Gravatar... jay Adair Apr 02, 2009 8:59 AM
# re: Grouping Controllers with ASP.NET MVC
Thanks Phil! One thing though; forms. The Html.BeginForm() helper no longer works as it doesn't look in the area for the controller action.

Do you have anything for this?
Requesting Gravatar... Jeremy Caney Apr 04, 2009 9:52 AM
# re: Grouping Controllers with ASP.NET MVC
Hey Phil - I'm very happy to see this. This has been one of my primary concerns with the MVC approach from the beginning since my firm tends to work on large websites which often contain multiple applications. I also appreciate that your approach solves this at a relatively fundamental level thus hiding the implementation details from (most of) the application; I had come up with a work around for this problem but it was implemented at a higher level and, therefore, was more invasive in terms of the actual application code.
Requesting Gravatar... SneWs May 12, 2009 5:16 AM
# re: Grouping Controllers with ASP.NET MVC
Nice post.
I like the solution.

Now I only have to implement/find a solution to the Html.BeginForm( ... ) and it's a go with this.


Tanks man!
Requesting Gravatar... Steve May 13, 2009 1:09 PM
# re: Grouping Controllers with ASP.NET MVC
Phil,

Has there been any update for MVC 1.0 on Areas ?

Do you have any updates to your prototype?
Requesting Gravatar... Steve May 13, 2009 3:24 PM
# re: Grouping Controllers with ASP.NET MVC
I got it to work.

Any ideas on how to use the Futures with this?

ie.
<%= Html.ActionLink<Areas.MyArea.Controllers.HomeController>(c => c.Index(), "Link", new { area="MyArea" } )%>

?
Requesting Gravatar... David Vu May 17, 2009 6:31 AM
# re: Grouping Controllers with ASP.NET MVC
Thanks for sharing your great ideas. It is exactly what
I was looking for to organize my project.
Just curious, have you looked at the nested areas concept you
mentioned at the end?
Requesting Gravatar... Aaron Janes May 30, 2009 9:48 PM
# re: Grouping Controllers with ASP.NET MVC
Thanks for this great bit of code Phil. One small thing is that all your areas routes assume a default controller of "HomeController" and a default action of "Index". This may be fine 99% of the time but maybe not in the other 1%. To handle this I've modified your AreaRouteHelper slightly and posted it as a text file here:

www.peppermint-it.com/.../AreaRouteHelper.cs.txt
Requesting Gravatar... Chris Vann Jun 02, 2009 10:06 PM
# re: Grouping Controllers with ASP.NET MVC
I ran into some real performance issues with the the code from this article. My issues, research, and subsequent solution are documented on my blog at coder28.wordpress.com/.../areas-in-asp-net-mvc/

Thanks for the code! I'm really loving the MVC framework.
Requesting Gravatar... Kezzer Jun 10, 2009 9:24 AM
# re: Grouping Controllers with ASP.NET MVC
Excellent example, and it's exactly what I need. I do wonder, however, how to have just a single master page, with a single stylesheet for all areas within the site? Areas do not necessarily mean different looks for the site. What's the best solution to a unified masterpage and stylesheet directory?
Requesting Gravatar... Kezzer Jun 11, 2009 3:48 AM
# re: Grouping Controllers with ASP.NET MVC
Sorry, I just went through your AreaViewEngine which answers my previous question for me. So when are nested-nested areas coming into play?

What do you have to say?

(will show your gravatar)
Please add 7 and 1 and type the answer here: