3

I am a bit confused with the area routing. I created an area called Backbone. I have my default controller, views and models as well.

http://localhost:46870/ 

gives me the following error :

Multiple types were found that match the controller named 'home'. This can happen if     
the route that services this request ('{controller}/{action}/{id}') does not specify   
namespaces to search for a controller that matches the request. If this is the case,  
register this route by calling an overload of the 'MapRoute' method that takes a 
'namespaces' parameter.

The request for 'home' has found the following matching controllers:
LearnJavascript.Areas.BackBone.Controllers.HomeController
LearnJavascript.Controllers.HomeController

Here is backbone route(This came with scaffolding, I did not make any changes):

    public override void RegisterArea(AreaRegistrationContext context) 
    {
        context.MapRoute(
            "BackBone_default",
            "BackBone/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }
        );
    }

Default route (This came with scaffolding, I did not make any changes):

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

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }

I was thinking that unless the url starts with

http://localhost:46870/Backbone

the backbone area home will not be called. So, why is routing confused on this.

Most confusing part was when I called this url :

http://localhost:46870/home/index

It shows me the same error message. Why is MVC routing so much confused on this.

Iam using VS2013 and MVC5.

krillgar
  • 12,596
  • 6
  • 50
  • 86
Sumesh Kuttan
  • 1,333
  • 1
  • 17
  • 40
  • even in different areas you can't have 2 controllers with the same name. – Matt Bodily Jul 29 '14 at 18:43
  • I thought having the same controller names was the main purpose of having an area. – Sumesh Kuttan Jul 29 '14 at 18:44
  • 1
    Please check [Multiple types were found that match the controller named 'Home'][1] [1]: http://stackoverflow.com/questions/7842293/multiple-types-were-found-that-match-the-controller-named-home – Hamid Bahmanabady Jul 29 '14 at 18:52
  • @HamidBahmanabady I added the namespace to the global route and it started working fine. thanks. – Sumesh Kuttan Jul 29 '14 at 18:59
  • @MattBodily We can have the same controller name in areas. That is one of the main purpose of having areas. I just created another area and double checked it. :) – Sumesh Kuttan Jul 29 '14 at 19:00
  • "I was thinking that unless the url starts with [Backbone] the backbone area home will not be called." It's actually the opposite. If you use the URL with the `Backbone` prefix, then there's no ambiguity, and the right controller is called. But, otherwise, all "Home" controllers could potentially match, therefore you need to specify a namespace on the route to remove the ambiguity. – Chris Pratt Jul 29 '14 at 20:46
  • @ChrisPratt Using the backbone prefix clears the ambiguity. But when a url is called without the backbone prefix, i think it is very clear (at least to me) that it should fall to the route outside the area. Why is MVC confused about this. Its very clear that if I want an area controller, I will be calling with the area name prefix. – Sumesh Kuttan Jul 30 '14 at 08:52
  • Not necessarily. See, the physical path of the controller does not matter. Once they're compiled there's no physical path anymore. Now, they will likely be in different namespaces, but when routing framework kicks in it simply requests "controllers", basically anything that inherits from `Controller` and searches these to find an action to handle the route. Your area route dictates a specific namespace to search within, so there's no ambiguity, but your default route doesn't, so any "Home" controller, regardless of what namespace it's in matches. – Chris Pratt Jul 30 '14 at 17:09
  • @ChrisPratt Nice point. Justifies the need for namespace. – Sumesh Kuttan Aug 01 '14 at 10:27

2 Answers2

5

I got the correct answer from HamidBahmanabady.

I added the namespace to the global route and it started working fine.

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new[] { "Test.Controllers"}

and

        context.MapRoute(
            "BackBone_default",
            "BackBone/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional },
            new[] { "Test.Areas.Backbone.Controllers" }
Sumesh Kuttan
  • 1,333
  • 1
  • 17
  • 40
  • hi, I've tried yours code, but it comes an error again The request for 'Health' has found the following matching controllers: Appname.Areas.Admin.Controllers.HealthController Appname.Controllers.HealthController, **What should I do?** – Karthic G Sep 26 '16 at 13:21
1

try this,

In route.config

routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        namespaces: new string[] { "Test.Controllers"}

and Admin section --> AdminAreaRegistration.cs

  context.MapRoute(
        "BackBone_default",
        "BackBone/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional },
        new string[] { "Test.Areas.Backbone.Controllers" }