shole
shole

Reputation: 4094

Multiple types were found that match the controller named 'XXX'

Currently I have 3 namespaces: Controllers, Controllers.AControllers, Controllers.BControllers

Basically A & B are just some types to distinguish two similar but different categories.

Now in both Controllers.AControllers and Controllers.BControllers, there is a controller named MyController and action named Detail_Index

And when use input an URL is of form ZZZ/A/{id}, I expect it will redirect them to call the controller/action in Controllers.AControllers, similar for ZZZ/B/{id}

Yet the outcome is not as I expected, it seems like the path skip the first rule, or match the default rule. and gives Multiple types were found that match the controller named 'MyController'

Why is that happening and how could I get the behavior I desired? Below is the RouteConfig I currently using.

routes.MapRoute(
  "A",
  "ZZZ/A/{id}",
  new
  {
    controller = "MyController",
    type = "A",
    action = "Detail_Index",
    id = UrlParameter.Optional,
  },
  new string[] { "Controllers.AControllers" }
);

routes.MapRoute(
  "B",
  "ZZZ/B/{id}",
  new
  {
    controller = "MyController",
    type = "B",
    action = "Detail_Index",
    id = UrlParameter.Optional,
  },
  new string[] { "Controllers.BControllers" }
);


routes.MapRoute(
  name: "Default",
  url: "{controller}/{action}/{id}",
  defaults: new
  {
  controller = "BaseController",
  action = "Search_Index",
  id = UrlParameter.Optional,
  },
  namespaces: new string[] { "Controllers" }
);

EDITED

After some further research, I found that I may use the "Area" features to cater my problem...Still have no concrete idea though, will delete this question if I try using "Area" and success.

Upvotes: 0

Views: 556

Answers (2)

NightOwl888
NightOwl888

Reputation: 56909

You are not correctly following conventions. I put this code into a sample project and was able to modify the project to follow the conventions you specified to get it working. But these are not the default conventions that Visual Studio creates, which is likely why you are having issues.

Namespaces

Your namespaces are most likely specified incorrectly. By default, Visual Studio sets up the namespaces like MvcApplication20.Controllers.AControllers, not Controllers.AControllers. A partial namespace won't work, you need to specify the entire namespace(s) where controllers that the route uses physically exist.

Controller Names

MVC automatically chops off the Controller suffix when comparing with the route values. The way you have it configured now, your controllers would have to be named MyControllerController and BaseControllerController in order for it to match.

Since you mentioned your controller is actually named MyController, you should specify My in the default route values and/or URL. I am guessing the same convention should be supplied for your BaseController.

Upvotes: 1

Tanya Petkova
Tanya Petkova

Reputation: 155

Here is a sample way how you could do that with Areas:

Add two new Areas to your MVC project, called A and B or whatever you need to. Add MyController class with Detail_Index action and the corresponding views to each of the areas:

namespace MyApp.Areas.A.Controllers
{
  public class MyController : Controller
  {
    public ActionResult Detail_Index()
    {
        return View();
    }
  }
}

namespace MyApp.Areas.B.Controllers
{
  public class MyController : Controller
  {
    public ActionResult Detail_Index()
    {
        return View();
    }
  }
}

Than you should register the preferred routes in the corresponding configuration classes:

    public override void RegisterArea(AreaRegistrationContext context) 
    {
        context.MapRoute(
            "A",
            "ZZZ/A/{id}",
            new { controller = "My", action = "Detail_Index", id = UrlParameter.Optional }
        );
    }

    public override void RegisterArea(AreaRegistrationContext context) 
    {
        context.MapRoute(
            "B",
            "ZZZ/B/{id}",
            new { controller = "My", action = "Detail_Index", id = UrlParameter.Optional }
        );
    }

You should call:

   AreaRegistration.RegisterAllAreas();

in Application_Start method in Global.asax to register the new routes and it's done.

Upvotes: 0

Related Questions