I'm new to Asp.Net MVC, due to some issues I've been having with Routes I discovered Glimpse and thought I'd give it a go, but I couldn't get the Glimpse.axd config page up, constantly getting a HTTP 404.
I made a new project and tried that, it worked fine. Through trial and error I eventually found that the problem is in the AreaRegistration file for my areas, if I do this:
context.MapRoute(
"SomeArea_default",
"Area/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
It works, I can get to the page, but if I leave out the area part
context.MapRoute(
"SomeArea_default",
"{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
then it doesn't.
I have previously asked whether that part was optional and I thought it was: Area routing, why is the area name needed?
I'm putting it back in to get things working, whats the actual reason behind this? Should that always be there or is this a Glimpse bug?
What you are describing is actually normal behavior and has everything to do with the order in which routes are being registered.
Let me explain it, based on a green field project as the one you created to pinpoint the problem.
When you create a new MVC project and you add a Test
area for instance, then you'll find the following types and methods inside your project:
A TestAreaRegistration
class defined as:
public class TestAreaRegistration : AreaRegistration
{
public override string AreaName
{
get { return "Test"; }
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Test_default",
"Test/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
An Application_Start
method inside your global.asax
defined as:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
A RouteConfig
class inside the App_Start
folder defined as:
public class RouteConfig
{
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 }
);
}
}
Now it is just a matter of reading through the startup code with regards to registering the routes for the application:
First the areas are being registered AreaRegistration.RegisterAllAreas();
That call will result in TestAreaRegistration.RegisterArea(...)
being called which will register the route Test/{controller}/{action}/{id}
Then the call to RouteConfig.RegisterRoutes(RouteTable.Routes)
will be made which will register the default {controller}/{action}/{id}
route and also registers a route to ignore .axd
requests.
now it is important to keep in mind that first all routes defined by the Test
area will be checked and then the ones defined by the RouteConfig
in case it is not a Test
area related route
Now what does this mean when you request /glimpse.axd
with this default setup ?
The route that will match is the route that is ignored inside the RouteConfig
because the routes that will be handled by your Test
area must start with Test/
which is clearly not the case for /glimpse.axd
but if you remove the Test/
part from the Test/{controller}/{action}/{id}
route registration inside the Test
area registration, then the route that will match the /glimpse.axd
request will now be handled by the routes defined by the Test
area as it will basically act as a catch all, and since it will not find a match a 404 is returned.
TL;DR
Now you can solve this in 2 ways:
Add context.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
to the top of the TestAreaRegistration.RegisterArea
method and the route will be ignored like it is in the default situation
Switch the AreaRegistration.RegisterAllAreas();
with the RouteConfig.RegisterRoutes(RouteTable.Routes)
so that the RouteConfig
routes will be matched first
Personally I would go for option 1 as it has the least impact.