It is not necessarily to map every controller physycal folder to route, you can organize you folder structure as you want, but if you want automatically map routes to all tree substructure - you can explore subnamespaces in your Controllers
folder and automatically map it to you routes without any hardcode, there is my solution:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using System.Web.Routing;
namespace WebApplication2
{
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 }
);
routes.MapAllRoutesToFolders();
}
}
public static class RouteExtensions
{
public static void MapAllRoutesToFolders(this RouteCollection routes)
{
const string commonControllerUrl = "{controller}/{action}/{id}";
var folderMappings = GetSubClasses<Controller>()
.Select(x => new
{
Path = string.Join("/", x.FullName
.Split(".".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
.SkipWhile(c => c != "Controllers"))
.TrimStart("/Controllers/".ToCharArray())
.Replace(x.Name, string.Empty),
Name = x.Name.Replace("Controller", string.Empty)
});
var controllerPaths =
folderMappings.Where(s => !string.IsNullOrEmpty(s.Path))
.Select(x => new
{
ControllerName = x.Name,
Path = x.Path + commonControllerUrl
});
foreach (var controllerPath in controllerPaths)
{
routes.MapRoute(null, controllerPath.Path, new { controller = controllerPath.ControllerName, action = "Index", id = UrlParameter.Optional });
}
}
private static IEnumerable<Type> GetSubClasses<T>()
{
return Assembly.GetCallingAssembly().GetTypes().Where(
type => type.IsSubclassOf(typeof(T))).ToList();
}
}
}
In that case, you folders structure should be like this:
After that you can check it in your browser: