Area Hype:
I wouldn't recommend applying Areas just because you can.
That would be like "giving a man a hammer and suddenly everything's a nail".
In this case we have a cool feature called "Areas" and (without knowing the underlying architecture)
others recommended it the instant someone asks about sub-folders.
Areas weren't designed for the sole purpose of giving you an extra Route Parameter.
The "Areas" original intent is to give you a clear SoC (Separation of Concerns).
For Example:
Say you have two separate web application experiences and have decided to roll them under one Solution.
Your call-center may need to look up detailed information and enter in data on individual customers,
while your managers and executives will peruse higher-level reporting and rarely enter in data.
In this scenario it may make sense to split your business logic into "Reporting" and "CallCenter" Areas.
Sub-Directories:
In MVC, the Sub-Folders you use under "Controllers" are Ignored when it comes to Routing.
SubFolders are perfectly fine with how the Questioner is using them to organize his Controllers.
Adding a SubFolder name to his URL makes for a more human-readable URL too.
He just made a mistake in the exclusivity of his first Mapping Route.
The problem is it was matching on everything.
Just because you have "settings/" in your MapRoute doesn't mean it will apply only to incoming URL's.
MVC will use your MapRoute Logic to figure how you would like to write your URL's too!
The Fix (Option 1 - Use MapRoute):
routes.MapRoute(
name: "Settings",
url: "Settings/{controller}/{action}/{id}",
defaults: new { action = "Index", id = UrlParameter.Optional },//Remove the Default Controller as we want to explicitly require it and constrain it. - 08/26/2018 - MCR.
constraints: new { controller = "Users|Admins" }//If you have other Controllers under a SubFolder (say we also had AdminsController.cs), then simply Pipe-Delimit them. - 08/26/2018 - MCR.
);
This is the way I've chosen to go, but if you want tighter control, you could use the Option below instead.
The Fix (Option 2 - Use Route-Attributes):
First, make sure you enable this feature by adding routes.MapMvcAttributeRoutes():
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();//Add this BEFORE MapRoute for Route-Attributes to work.
Next, Decorate your Controller with the following Attributes:
(You may even include Default/Optional Values, just like in your MapRoute.)
[RoutePrefix("Settings/Users")]//Add your ParentFolder and Include your Controller name too.
[Route("{action=Index}/{id?}")]//You need this if you are using the RoutePrefix Attribute. Without this, you will need to define "[Route]" above every Action-Method. - 08/26/2018 - MCR.
public class UsersController : Controller
Note:
If you use Route-Attributes instead of MapRoute, then you will not be able to hit the
Controller without the "Settings" Prefix.
With the Custom and Default MapRoutes, you could have accessed your controller either way.
By decorating your Controller with these Attributes, you now force it to only use this exact path.
This may be what you want, but if you start IIS Express from Visual Studio on one of your Views,
then it will not find it because Visual Studio does not know to add the RoutePrefix for you.
I say this, so you are not discouraged when you start debugging and think it doesn't work.
See this link for more information about Attribute-Routing:
https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/