28
votes

In MVC3, I have the following areas:

  • Mobile
  • Sandbox

Then i route maps like this:

    context.MapRoute(
        "Sandbox_default",
        "Sandbox/{controller}/{action}/{id}",
        new { controller = "SandboxHome", action = "Index", id = UrlParameter.Optional }

and

    context.MapRoute(
        "Mobile_default",
        "Mobile/{controller}/{action}/{id}",
        new { controller = "MobileHome", action = "Index", id = UrlParameter.Optional }
    );

The problem is this gives urls like:

http://localhost:58784/Mobile/MobileHome

and

http://localhost:58784/Sandbox/SandboxHome

But I want it like this:

http://localhost:58784/Mobile/Home
http://localhost:58784/Sandbox/Home

The problem is when I rename the SandboxHome-Controller to Home, and the MobileHome-Controller to Home, which would give the desired URLs, it won't compile, saying it has two classes for HomeController.

How can I have the same controller name in different areas ?

2

2 Answers

42
votes

Yes.

As explained by this blog post: http://haacked.com/archive/2010/01/12/ambiguous-controller-names.aspx

Assuming you have a call to RegisterAllAreas and the AreaRegistration files generated by Visual Studio. All you need to do is the namespace on the default route in global ASAX to prevent conflicts.

//Map routes for the main site. This specifies a namespace so that areas can have controllers with the same name
routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        new[]{"MyProject.Web.Controllers"}
 );

As long as you keep the Area controllers within their own namespaces. This will work.

5
votes

Yes it is but you'll have to change your routing:

context.MapRoute(
    "Default",
    "{area}/{controller}/{action}/{id}",
    new { area = "Mobile", controller = "Home", action = "Index", id = UrlParameter.Optional }
);

You could as well keep both routes but don't forget to define area in your defaults.

Important

Of course you must keep controllers in their own area namespaces:

namespace MyApp.Areas.Mobile.Controllers
{
    public class HomeController : Controller
    {
        ...
    }
}

namespace MyApp.Areas.Sandbox.Controllers
{
    public class HomeController : Controller
    {
        ...
    }
}

Check this link on MSDN and see the walktrough. And don't forget to also check out this MSDN article that talks about area registration, because you will have to call RegisterAllAreas() method.

And since you still want to keep original non-area controllers, you should also read this Phil Haack's article how to do just that (Credit should go to @Rob in his answer for pointing to this blog post first).