1

I'm fairly new to MVC3, but I've spent quite a bit of time researching this and testing, and I cannot find a solution. There is another similar post on Stack, but it's unanswered after 7 months.

The crux is this: If you have areas and controllers with duplicate names - no problem. If you have areas and use HyphenatedRouteHandler - no problem. If you try to use areas, duplicate controller names and the hyphenated route handler, you get the error:

Multiple types were found that match the controller named 'products'. 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.

I should also add, I'm getting the error on the root controller, but not the controller within the area. Eg, /products does NOT work, but /admin/products DOES work.

I will be eternally grateful for a specific solution!! The code looks like this:

Global.asax

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

        var route = routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
            new[] { "MyProject.Controllers" }
        );

        route.RouteHandler = new HyphenatedRouteHandler();
    }

And:

    public class HyphenatedRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        requestContext.RouteData.Values["controller"] = requestContext.RouteData.Values["controller"].ToString().Replace("-", "_");
        requestContext.RouteData.Values["action"] = requestContext.RouteData.Values["action"].ToString().Replace("-", "_");

        return base.GetHttpHandler(requestContext);
    }
}

AdminAreaRegistration.cs

public class AdminAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        {
            return "Admin";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "Admin_default",
            "Admin/{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}
jstafford
  • 418
  • 6
  • 14
  • In your route for your area, have you tried adding the area's namespace, as you have for your default route in Global.asax.cs? – counsellorben Jul 28 '11 at 04:08
  • I added it, so now it looks like – jstafford Jul 28 '11 at 05:40
  • public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "Admin_default", "Admin/{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new[] { "MyProject.Areas.Admin.Controllers" } ); } but no luck - I still get the same error when I hit the root /products page. – jstafford Jul 28 '11 at 05:41

1 Answers1

1

You need to specify the area in your HyphenatedRouteHandler :

requestContext.RouteData.DataTokens["area"] = requestContext.RouteData.Values["area"].ToString().Replace('-', '_');

YTZGuy
  • 36
  • 2
  • Thank you for the reply! I have not had a chance to test it, as I basically had to work around it. As soon as I'm done with my project I will circle back and test this, but I will mark it as the answer for now as it seems to look right. – jstafford Aug 30 '11 at 02:54