我的解决方案具有与业务结构相匹配的深层文件夹结构,深入3-4级,例如:
\Franchises
\Regionals
\Billing
\Monthly
\...
\...
\...
\...
\...
\...
\...
\...
域,进程和报告项目中的文件夹结构与此结构一致。
MVC是一种痛苦。默认情况下,它只允许1级深度:\Controllers\BlahBlah
使用MVC区域我可以获得2级深度(klutzily在路径中添加两个文件夹):
\Areas\Franchises\Controllers\BlahBlah
这远不足以反映业务的深层结构。
我对将WebUI垂直分割成多个项目犹豫不决,因为这需要进一步的整合工作,而且似乎只是强加了业务结构。
有没有办法将任意文件夹级别强加到MVC项目中?我应该手动硬编码所有控制器路由吗?
答案 0 :(得分:2)
不一定要将每个控制器physycal文件夹映射到路由,您可以根据需要组织文件夹结构,但如果要自动将路由映射到所有树子结构 - 您可以浏览Controllers
文件夹中的子名称空间并自动将其映射到您的路线,没有任何硬编码,有我的解决方案:
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();
}
}
}
在这种情况下,您的文件夹结构应该是这样的:
之后,您可以在浏览器中查看它: