MVC 3 Area route not working

24,003

Solution 1

The registration in your area appears to be wrong. You specify a default for your action but not for the controller. Since you typically have Home as the name of the controller you'd need to specify that.

Also it could be you don't have your folders setup correctly since you should have physically setup:

  • /Areas/Blog
  • /Areas/Blog/Controllers
  • /Areas/Blog/Views

... and once you have fixed your blog area route you'll also need:

  • /Areas/Blog/Views/Home << Put your index view in here

The error you get seems to pretty clearly indicate this is the issue.

Solution 2

I found what I consider to be a bug in the framework, with a workaround. If you are trying to map a default route to an MVC 3 app with areas, your global.asax file might have something like this:

VB:

routes.MapRoute(
      "Default",
      "{area}/{controller}/{action}/{id}",
      New With {.area = "MyArea", .controller = "Home", .action = "Index", .id = UrlParameter.Optional}
)

C#:

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

If you go to your app root in the URL, you may get a runtime error like this:

The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:

For some reason, the view engine does not appear to look in the area folder for the view file the same as if you type in the whole link. The strange thing is the code reaches the controller action. Here is the fix: Put this code in your controller action:

VB:

If Not Me.ControllerContext.RouteData.DataTokens.ContainsKey("area") Then
                Me.ControllerContext.RouteData.DataTokens.Add("area", "MyArea")
            End If

C#

  if (!this.ControllerContext.RouteData.DataTokens.ContainsKey("area"))
{
        this.ControllerContext.RouteData.DataTokens.Add("area", "MyArea")
 }

Solution 3

I'm using Phil Haack's routedebugger to troubleshoot problems such as this one. It conveniently shows all registered routes and how the entered URL matches your configuration.

It works by overriding the regular application flow, which you enable by adding this line at the end of Application_Start:

RouteDebug.RouteDebugger.RewriteRoutesForTesting( RouteTable.Routes );

Solution 4

Relax! This can save you hours of reading, make a coffee and watch this 3 minutes video, everything will be clear to you. http://www.asp.net/mvc/videos/mvc-2/how-do-i/aspnet-mvc-2-areas (I belive it also works for mvc3, mvc4, and mvc2035) enter image description here

Solution 5

Following on from Mortens answer, you can now NuGet (or manually download and install) the RouteMagic, or Glimpse packages which provides this functionality, and more.

More information is available on Phil Haacks blog regarding the state of his tool and what it has morphed into. The comments make for good reading too!

Share:
24,003

Related videos on Youtube

Marco
Author by

Marco

Specialities: Go React.js Docker Kubernetes Zero Trust Architecture Domain Driven Design CQRS Eventsourcing C# Twitter: @marcofranssen Personal Webblog: https://marcofranssen.nl

Updated on February 05, 2020

Comments

  • Marco
    Marco over 4 years

    I created a Area in my MVC 3 application called 'Blog'.

    In global.asax I have the following code.

    public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );
        }
    
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
    
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
    
        }
    

    This is the code of my Area

    public class BlogAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get { return "Blog"; }
        }
    
        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "Blog_default",
                "Blog/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional }
            );
        }
    }
    

    When I go to the following url http://localhost/CMS/blog I get the following error.

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

    How do I solve this?

  • Marco
    Marco about 13 years
    Ok and how do I solve my blog route isn't catched by my routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults ); Route
  • Morten Mertner
    Morten Mertner about 13 years
    First look to see whether you area routes are shown by routedebugger. If they are not then RegisterAllAreas is not being called or not working. If they are listed, but an url like "/blog/ctrl/act" is not matched by your blog area routes, it's a different problem. Note that I have "dataTokens: new { area = "blog" }" as an additional parameter on my area registrations, although if I remember correctly this was an MvcFutures requirement. Worth trying if stuff doesn't work though.
  • trevorc
    trevorc over 11 years
    This is also useful for routing between areas. e.g. ControllerContext.ParentActionViewContext....etc.
  • Peter Gfader
    Peter Gfader about 11 years
    I wish VS tooling would have created that for us :-( new { controller="Home", action = "Index", id = UrlParameter.Optional }
  • Imad Alazani
    Imad Alazani almost 11 years
    Hello @Peter : I was checking the DatTokens in Controller Context. I found that the DataToken's key count = 0 when I am in Root Directory Controller. Is this a fact?
  • Imad Alazani
    Imad Alazani almost 11 years
    @MortenMertner : I was checking the DatTokens in Controller Context property. I found that the DataToken's key count = 0 when I am in Root Directory Controller. Is this a fact?
  • Imad Alazani
    Imad Alazani almost 11 years
    @MindstormInterface : I was checking the DatTokens in Controller Context property. I found that the DataToken's key count = 0 when I am in Root Directory Controller. Is this a fact?
  • Imad Alazani
    Imad Alazani almost 11 years
    I was checking the DatTokens in Controller Context property. I found that the DataToken's key count = 0 when I am in Root Directory Controller. Is this a fact?
  • Peter
    Peter almost 11 years
    @PKKG - DataTokens are values you specify when registering the route and do not comes from the URL. Try looking at Controller Context's RouteValues collection - these are values which are specified in route and matched from the URL.
  • Mindstorm Interactive
    Mindstorm Interactive almost 11 years
    @PKKG Yes I just tested this out and got the same result. The framework should provide the default values from global asax. Maybe global isn't set up right but that's how it is in all the examples and the fix in the controller works so I didn't dwell on it.