Ambiguous Controller Names With Areas

Note: This describes the behavior of ASP.NET MVC 2 as of the release candidate. It’s possible things might change for the RTM.

When using areas in ASP.NET MVC 2, a common problem you might encounter is this exception message.

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

This message is telling you that the controller factory found two types that match the route data for the current request. Typically this happens when you have a controller of the same name in an area and in the main project.

For example, in the screenshot below, notice that we have a HomeController in the main Controllers folder as well as in the Blogs area.

area-with-ambiguous-controller

If you make a request for the area such as /Blogs/Home, you’ll find that everything works hunky-dory. However, if you make a request for the root HomeController, such as /Home, you’ll get the ambiguous controller exception.

Why is that?

When you register routes for an area, they get a namespace associated with each route. That ensures that only controllers within the namespace associated with that area can fulfill the request. Thus the request that matches an area will have that namespace and the namespace is used to disambiguate controllers.

But by default, the routes in the main application don’t have a namespace associated with them. That means the controller factory will scan all types looking for a match, and in this case finding two types which match the controller name “Home”.

The Fix

There are two very simple workarounds. The simplest falls in the “If it hurts, stop doing that” camp which is to simply avoid naming two controllers the same name.

For many situations, this is not a satisfactory answer. The other workaround, as you might guess from my explanation of why this happens, is to give the route in the main application a specific namespace. Here’s an example of the default route in Global.asax.cs which has the fix.

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

  routes.MapRoute(
    "Default",                                              // Route name
    "{controller}/{action}/{id}",                           // URL
    new { controller = "Home", action = "Index", id = "" }, // Defaults
    new[]{"AreasDemoWeb.Controllers"}                       // Namespaces
  );
}

In the code above, I added a fourth parameter which is an array of namespaces. The controllers for my project live in a namespace called AreasDemoWeb.Controllers.

Follow Up

In a follow-up post, I’ll walk through more details about areas and how namespaces play into routing and controller lookup. For now, I hope this gets you unstuck if you’ve run into this problem before.

Technorati Tags: ,,

What others have said

Requesting Gravatar... Chris Hardy Jan 12, 2010 10:08 AM
# re: Ambiguous Controller Names With Areas
Hey Phil,

I came across this problem pretty quickly in the early beta. I think the Namespace fix isn't too bad at all.

Good work!

ChrisNTR
Requesting Gravatar... Paco Jan 12, 2010 10:49 AM
# re: Ambiguous Controller Names With Areas
Today I noticed the controllerfactory and mvchandler do not allow to call a controller just "Controller". I could not find any reason for that. The controllerfactory can cache the right controllertype with string.empty. I think it's a good convention for simplicity to call controllers ...Controller, but I think the mvc framework should not enforce programmers to use a convention which has no technical reasons. I would really like to see the conventions that are not used by mvc to be removed.
Requesting Gravatar... Craig Jan 12, 2010 10:57 AM
# re: Ambiguous Controller Names With Areas
When I first heard of "areas", I assumed MVC would support URLs like Blogs/Home/Index and that I could create route definitions like {area}/{controller}/{action}/{id} and MVC would use the area part of the URL to distinguish controllers.

Your fix removes the ambiguity for the compiler, but from the standpoint of creating URLs, do I have to name the Blogs Home controller different from the Forums Home controller? I can see a lot of naming inconvenience just to avoid ambiguity.
Requesting Gravatar... Simon W Jan 12, 2010 3:44 PM
# re: Ambiguous Controller Names With Areas
I also found this same problem and the namespace fix early on.

What I think though is an outstanding issue (which I nearly reported) is if one namespace is a descendent namespace of the other you still get the error.

For instance I had

SimonsWebsite.Controllers

and

SimonsWebsite.Controllers.FunStuff

and would still receive an 'ambigious controller' error if those two namespaces contained the same controller.

Of course I fixed this by making the namespaces completely unique.

PS. I forget the *exact* details if I had Controllers.FunStuff or FunStuff.Controllers, and I wan't going to mention this anyway but since you did I thought it might be of use (especially if a change is made for RTM).
Requesting Gravatar... Thanigainathan Jan 13, 2010 1:42 AM
# re: Ambiguous Controller Names With Areas
I agree with Craig .Why should the area name be a parameter in the url ?
Requesting Gravatar... Nick Kirkes Jan 13, 2010 8:47 AM
# re: Ambiguous Controller Names With Areas
On a related note, I've been having trouble getting an area to recognize a default controller. For example, if I have an Admin area defined and want the default controller for that area to be a DashboardController, specifying the controller in the base route doesn't send the url "~/Admin/" to the correct resource (it doesn't find any resource to display). If I try "~/Admin/Dashboard", then it works just fine. I have a post on StackOverflow and would really appreciate some input. Perhaps this is a bug?

SO post: stackoverflow.com/...

P.S. Sorry to hijack the comment thread, but at least there's some relationship to the main topic.
Requesting Gravatar... Becker Jan 14, 2010 12:45 PM
# re: Ambiguous Controller Names With Areas
On a somewhat related note, where has the Microsoft.Web.Mvc.Build.dll assembly gone from the MVC2 RC release.

It was present in the Preview 2 release (within VS2008 Tools installer) but is no longer present in RC. Is this no longer supported?
Requesting Gravatar... haacked Jan 14, 2010 11:40 PM
# re: Ambiguous Controller Names With Areas
@Becker that's correct, it's been moved to the MVC Futures assembly.
Requesting Gravatar... Jarek Jan 18, 2010 4:06 PM
# re: Ambiguous Controller Names With Areas
Sorry, but I can't find it in futures zip file.
Requesting Gravatar... Jarek Jan 19, 2010 12:41 PM
# re: Ambiguous Controller Names With Areas
Ok I have a solution:
stackoverflow.com/.../2096884#2096884
Requesting Gravatar... Derek Jan 24, 2010 1:14 PM
# re: Ambiguous Controller Names With Areas
Not to sound rude or anything - but this seems to me that it will be an excessively common problem.

I would really advise these instructions being in the release notes - both for the release candidates, and the final - or some kind of tooling, comment, etc, in the final build output that elaborates it.
Requesting Gravatar... Tom John May 20, 2010 11:21 AM
# re: Ambiguous Controller Names With Areas
This works a treat (although have to agree that it should really be handled like controllers and actions in the routes).

That asside - I've found that if the controller is in an alternate assembly, it seems that from within an area the controller cannot be resolved. Controllers works fine in alternate assemblies when there are no areas involved.

Is there a solution to this situation?

What do you have to say?

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