0

When I use this URL:

http://www.domain.com/Dashboard/Admin/Index

My page works as expected. Dashboard is an MVC Area, Admin is the controller and Index is the view.

If I remove the area name, like this:

http://www.domain.com/Admin/Index

Then I get the following error:

Server Error

That's only kind-of expected; shouldn't it be a 404?

Why does MVC still successfully locate the controller and attempt to find the view when I don't specify the area?

How do I force it to return 404 when area is not included?

I've tried changing namespaces but it doesn't make a difference.

Rowan Freeman
  • 15,724
  • 11
  • 69
  • 100
  • Do you have a default route with no area in it like `{controller}/{action}/{id}`? – asymptoticFault Aug 27 '13 at 01:29
  • Yes. It's just a standard MVC4 project. You can test this by creating a new MVC project, creating a new area as described above and then testing the different URLs. – Rowan Freeman Aug 27 '13 at 01:57
  • If you remove the default route and only have routes for areas then you might get a 404 instead of the message above. – asymptoticFault Aug 27 '13 at 02:04
  • That sounds about right. Not quite a solution but good information nonetheless. – Rowan Freeman Aug 27 '13 at 02:16
  • I would say it's as good a solution as there is using the default behavior. That being said, just about everything can be overridden or extended in MVC so you would need to override the class or method that matches routes to detect when the area is not supplied and return a 404. Now detecting when the area is not supplied is an interesting question because a route would have to be matched in order to determine that an area had not been supplied because it is the routes that give definition to each segment of the URL. – asymptoticFault Aug 27 '13 at 02:37

1 Answers1

1

By default the built-in controller factory will find all implementations of matched controllers regardless of namespace. While the view engine will search for the associated view in context of the request (i.e. won't search in an area if the area route has not been matched). In short you need to limit the route engine definitions to only search in 'defined' namespaces, then the 404 will be thrown.

This is accomplished by using an overload of the MapRoute method, and passing the namespaces:

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
    null, // object constraints
    new string[] { "Namespace.Application.Controllers" } // namespaces
);

For experimental purposes to see what the controller factory does with multiple controllers of the same name, try adding another AdminController to the root Controllers folder and then run the same request.

Brent Mannering
  • 2,316
  • 20
  • 19