在ASP.NET MVC中强加深层业务结构的选项?

时间:2014-02-10 03:18:07

标签: asp.net-mvc structure asp.net-mvc-areas

我的解决方案具有与业务结构相匹配的深层文件夹结构,深入3-4级,例如:

\Franchises
   \Regionals
      \Billing
         \Monthly
         \...
         \...
      \...
      \...
   \...
   \...
\...
\...

域,进程和报告项目中的文件夹结构与此结构一致。

MVC是一种痛苦。默认情况下,它只允许1级深度:

\Controllers\BlahBlah

使用MVC区域我可以获得2级深度(klutzily在路径​​中添加两个文件夹):

\Areas\Franchises\Controllers\BlahBlah

这远不足以反映业务的深层结构。

我对将WebUI垂直分割成多个项目犹豫不决,因为这需要进一步的整合工作,而且似乎只是强加了业务结构。

有没有办法将任意文件夹级别强加到MVC项目中?我应该手动硬编码所有控制器路由吗?

1 个答案:

答案 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();
        }
    }
}

在这种情况下,您的文件夹结构应该是这样的:

enter image description here

之后,您可以在浏览器中查看它:

enter image description here