asp.net-mvc-3c#-4.0asp.net-mvc-areasasp.net-mvc-3-areasmvcroutehandler

MVC3 RouteHandler result ignores Area in the resolved Route - why?


I am working on splitting an MVC3 Application into two Areas. The existing application is going into one area (V1) and we are beginning a redesign in the second area (V2).

I have the Views, Models, Controllers, etc all moved into the MyApp\Areas\V1\xxx folders, and I have been able to verify that things are loading as they should for the most part. I moved all the Route registration for V1 into the V1AreaRegistration.cs file, and modified it to use context.MapRoute instead of RouteTable.Routes.MapRoute.

Looking at the routing with Phil Haack's RouteDebugger, everything looks good - my V2 routes are resolving as they should, and the basic V1 routes work. What is NOT working are the V1 routes where I have a custom MvcRouteHandler defined such as this:

context.MapRoute(
    "MyRouteName",
    "{myRouteVal}/{controller}/{action}",
    new { area = "V1", controller = "DefaultController", action = "Index" },
    new { controller = _someRouteConstraint},
    new string[] { "My.Custom.Project.WebLibrary.Areas.V1.Controllers" },
        _myCustomRouteHandler);

If I remove the _myCustomRouteHandler from this call, it works great and sends me to the correct view under the V1 Area. With it in place, the routing seems to ignore the fact that it is registered as an Area route, and I get a yellow error page that says:

The view 'Index' or its master was not found or no view engine
supports the searched locations. The following locations were searched:
~/Views/DefaultController/Index.cshtml
~/Views/DefaultController/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml
~/Views/DefaultController/Index.aspx
~/Views/DefaultController/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx

I need to be able to use the route handler - it does some validation work on the {myRoutVal} parameter and redirects to an error page if it is invalid.

Help!!


Solution

  • Found the problem. We have an extension method for AreaRegistrationContext that you see referenced above (context.MapRoute) - in that method, I am not setting the route.DataTokens["Area"] value correctly, so when it tries to find the view, it doesn't look in the area.

    Adding the following line to my AreaRegistrationContext extension method solved the problem:

    route.DataTokens["Area"] = context.AreaName;