使用Areas分离ASP.NET MVC项目

摘要:
我们知道,MVC项目的每个部分的职责都是相对明确的,与ASP.NET Webform相比,MVC项目中的业务逻辑和页面呈现是很好地分离的。这种方法具有许多优点,如可测试性、易扩展性等。NetMVC提供了区域的概念来实现这一目标。因此,可以有条件地限制默认路由。请参考Stephen Walther的ASP NETMVCTip#30–CreateCustomRouteConstraints。将默认路由修改为:?对于第二个改进,主要主题是使用Areas函数来分隔。

为什么需要分离?

我们知道MVC项目各部分职责比较清晰,相比较ASP.NET Webform而言,MVC项目的业务逻辑和页面展现较好地分离开来,这样的做法有许多优点,比如可测试,易扩展等等。但是在实际的开发中,随着项目规模的不断扩大,Controller控制器也随之不断增多。如果在Controllers文件夹下面有超过两位数controller,即便采用良好的命名规范,或者用子文件夹的形式区分不同功能的控制器,还是会影响项目的可阅读性和可维护性。因此,在一些场景下,如果能把与某功能相关的文件分离到一个独立的项目中是非常有用的。Asp.Net MVC提供了Areas(区域)的概念达到这一目的。

一个典型的场景

Web应用通常会有前台(面向用户)和后台(面向管理员)两部分,我们希望以/locahost/Admin开始的URL都为后台管理地址,因此我们也许会有这样的路由:

1
2
3
4
5
6
7
8
9
10
11
routes.MapRoute(    //Admin Route
    "Admin", // Route name
    "Admin/{controller}/{action}/{id}", // URL with parameters
    new { controller = "Admin", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
 
routes.MapRoute(    //Default Route
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

运行程序访问locahost/Admin, 通过RouteDebugger(Asp.Net MVC路由调试的好帮手RouteDebugger)的输出信息可以看到,第一个路由(Admin)匹配成功,AdminController的Index方法被调用了,然而再仔细想想,通过/localhost/Admin/Index可以匹配第二个路由(Default),同样可以调用AdminController的Index方法!以此类推,后台用户管理列表(/localhost/Admin/User/List)等同于(/localhost/User/List)。

第一次改进

我们要达到一种目的,那就是/localhost/Admin/Admin/Index正确匹配第一个路由,而/localhost/Admin/Index不匹配第二个路由。因此可以对Default路由进行条件限制,参考Stephen Walther的ASP.NET MVC Tip #30 – Create Custom Route Constraints,修改Default路由为:

1
2
3
4
5
6
routes.MapRoute(    //Default Route
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
    new { controller = new NotEqual("Admin")}
);

上面的路由意思是AdminController不会匹配Default路由。现在分别运行之前的两个URL,会发现直接访问/Admin/Index已经不能匹配到任何路由。通过修改NotEqual类,可以很容易为Default路由添加多个“排除在外”的Controller限制条件。但是,你不觉得这样很挫么?

第二次改进

这里进入正题,使用Areas这个功能来进行分离。新建一个项目"MyMvcAreasDemo",然后在项目上右键->添加->Areas,输入"Admin",如下:

add area

在Areas/Admin/Controllers文件夹下面新建HomeController并添加一个Index的方法和对应的View文件。这里可以发现Areas的另一个好处:你可以在不同Areas下面添加相同名称的Controller。当然,如果你直接这么运行会得到一个错误:

area error

这种情况需要修改一下AdminAreaRegistration.cs和Global.asax,分别为路由加上命名空间限制:

/Areas/Admin/AdminAreaRegistration.cs

1
2
3
4
5
6
context.MapRoute(
     "Admin_default",
     "Admin/{controller}/{action}/{id}",
     new { action = "Index", id = UrlParameter.Optional },
     new string[] { "MyMvcAreasDemo.Areas.Admin.Controllers" }
 );

/Global.asax.cs

1
2
3
4
5
6
routes.MapRoute(    //Default Route
     "Default", // Route name
     "{controller}/{action}/{id}", // URL with parameters
     new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
     new string[] { "MyMvcAreasDemo.Controllers" }
 );

这样,我们就可以把所有与后台管理相关的Controller和View文件放到/Areas/Admin下面,以此类推,可以添加诸如会员(Member),博客(Blog),论坛(Forum)等多个Areas。各部分都有自己的顶层文件夹,物理文件都分离开来,管理起来比较方便。

这种方式已经有了很大提高,但是所有的文件还是放在同一个项目里面。当项目规模较大的时候,比较好的开发方式是将不同功能模块按需要独立到不同项目里面,最后再整合成一个整体。这样,每一个项目可以独立开发,测试和发布。

第三次改进

我们需要对现有项目进行一下改造:

1.  在解决方案上面新建一个MyMvcAreasDemo.Admin的MVC3项目,并且删除Global.asax和Web.config两个文件

2.  在根目录新建一个AdminAreaRegistration的类,输入如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class AdminAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        {
            return "Admin";
        }
    }
 
    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "Admin_default",
            "Admin/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }               
        );
    }
}

3.  删除MyMvcAreasDemo项目/Areas/Admin文件夹下面的AdminAreaRegistration.cs文件以及Controllers文件夹(包括HomeController)

4.  在MyMvcAreasDemo.Admin项目的Controllers里面新建一个HomeController

5.  记得保留MyMvcAreasDemo/Areas/Admin下面的Views,并且在MyMvcAreasDemo项目里面引用MyMvcAreasDemo.Admin项目,如图:

QQ截图未命名

现在运行程序并访问/Admin/Home/Index可以发现Admin项目生效了。这样,我们可以将所有的与后台管理相关的Controller都放到这个新的项目中来。但是很快你会发现,一个新的“问题”又出现了:

当你在MyMvcAreasDemo.Admin里面的HomeController添加新的Action(例如List),然后习惯性在上面右键-"Add View"后,你会发现新增的List.cshtml文件会出现在MyMvcAreasDemo.Admin/Views/Home下面,然后当你访问/Admin/Home/List的时候浏览器会得到错误提示:"The view 'List' or its master was not found or no view engine supports the searched locations…"。原来它只会在主程序MyMvcAreasDemo中的对应目录去寻找View。这么一来,MVC框架提供给我们的脚手架功能就大打折扣,当然你可以手动在MyMvcAreasDemo/Areas/Admin/Views中对应添加View,或者在MyMvcAreasDemo.Admin项目中自动生成了View之后再拷贝过去。有没有更好的办法呢?

第四次改进

为了使我们在MyMvcAreasDemo.Admin自动生成的View自动同步到MyMvcAreasDemo/Areas/Admin/Views文件夹中,可以使用“生成事件(Build Event)”里的“Post-Build Event”,打开MyMvcAreasDemo.Admin的属性,修改如下图所示:

1

我本地的生成事件为:

1
2
mkdir "$(SolutionDir)$(SolutionName)AreasAdminViews"
xcopy "$(ProjectDir)Views" "$(SolutionDir)$(SolutionName)AreasAdminViews" /S /E /C /Y

意思其实很简单,相信大家都能看得懂,就是完全复制MyMvcAreasDemo.Admin的Views文件夹下所有文件至MyMvcAreasDemo/Areas/Admin/Views中。

现在再次访问/Admin/Home/List就可以得到正确结果了,并且你可以发现List.cshtml已经被复制到MyMvcAreasDemo/Areas/Admin/Views/Home目录里。

至此大功告成!我们已经将面向前台和面向后台的模块成功分离到两个独立的项目中,希望能对您有所帮助!

===update===

另外一种分离方式:使用MvcContrib分离ASP.NET MVC项目

免责声明:文章转载自《使用Areas分离ASP.NET MVC项目》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Hive的访问接口 | Allen's WorldFDR & FWE下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

nginx+vue+thinkphp5.1部署,解决前端刷新404,以及前端404解决后,后台又404的问题

宝塔的话直接在网站的伪静态一栏中如下就行 location /admin { if (!-e $request_filename){ rewrite ^(.*)$ /index.php?s=$1 last; break; } } location / { try_files $uri $uri/ /index.php; }...

Win7下的内置FTP组件的设置详解

在局域网中共享文件,FTP是比较方便的方案之一。Win7内部集成了FTP,只是设置起来颇费一番功夫。着文以记之。 一、安装FTP组件 由于Win7默认没有安装FTP组件。故FTP的设置第一步就是安装FTP组件 点击:控制面板—》程序和功能—》打开或关闭Windows功能。勾选“FTP服务器”及“FTP服务”“FTP扩展性”,点击“确定”,安装FTP组件。如...

mongo部署(linux)

Linux版本:CentOS release 6.9 Mongodb版本:mongodb-linux-x86_64-3.6.1.tgz 1、解压文件 执行解压命令:tar -zxvf mongodb-linux-x86_64-3.6.1.tgz   2、创建数据,日志目录 命令:mkdir /my/mydata/mongodb       mkdir /m...

34个漂亮的应用程序后台管理界面(系列二)

今天这篇文章收集了34个漂亮的应用程序后台管理界面分享给大家。这些界面都是来自themeforest网站,虽然直接下载需要付费的,不过大部分都提供了在线预览,所以完全能够复制下来,有的提供了预览图,设计师可以根据预览图自己设计。希望这些漂亮的后台管理界面设计案例能帮助到你。(有登录界面的,点击登录即可进入后台界面) Flexy Admin Broom C...

分布式任务调度系统:xxl-job

任务调度,通俗来说实际上就是“定时任务”,分布式任务调度系统,翻译一下就是“分布式环境下定时任务系统”。 xxl-job一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。 gitee地址:https://gitee.com/xuxueli0323/xxl-job 中文文档地址:ht...

01. go-admin的下载与启动

目录 一.介绍 二.新建空文件夹 三.获取后台源码并启动 1.下载编译go代码 2.配置命令到goland IDE ,debug启动 四.获取前端ui源码并启动 1.下载编译go代码 2.启动项目 ** go-admin 基于Gin + Vue + Element UI的前后端分离权限管理系统** 系统初始化极度简单,只需要配置文件...