使用Areas分离ASP.NET MVC项目

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

典型场景

网站通常会有论坛(Forum)、会员(Member)、邮箱(Email)等多个板块,我们希望以/locahost/Forum开始的URL都是论坛管理地址,因此我们也许会有这样的路由:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Forum",
        url: "Forum/{controller}/{action}/{id}",
        defaults: new { controller = "Forum", action = "Index", id = UrlParameter.Optional }
    );

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

运行程序,访问localhost/Home/Index和localhost/Forum/Home/Index,发现浏览器显示的是同一个页面,说明用户的请求经过路由解析后结果都是HomeController下的Index视图,这明显不是我们想要的结果,访问localhost/Forum/Home/Index时应该返回与论坛相关的页面才对,现在你需要Areas来帮忙。

第一次改进

我们要达到一种目的,那就是localhost/Forum/Home/Index请求的是论坛页面,而localhost/Home/Index请求的是主页面。
现在进入正题,使用Areas功能来进行分离。新建一个项目”MvcDemo”,然后在项目上右键->添加->区域(Areas),输入”Forum”,如下:
这里写图片描述
在Areas/Forum/Controllers文件夹下面新建HomeController并添加一个Index的方法和对应的View文件。这里可以发现Areas的另一个好处:你可以在不同Areas下面添加相同名称的Controller。当然,如果你直接这么运行会得到一个错误:
这里写图片描述
这种情况需要修改一下ForumAreaRegistration.cs和RouteConfig.cs,分别为路由加上命名空间限制:
/Areas/Forum/ForumAreaRegistration.cs

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 },
        namespaces: new string[] { "MvcDemo.Controllers" }
    );
}

/App_Start/RouteConfig.cs

public override void RegisterArea(AreaRegistrationContext context)
{
    context.MapRoute(
        "Forum_default",
        "Forum/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional },
        new string[] { "MvcDemo.Areas.Forum.Controllers" }
    );
}

这样,我们就可以把所有与论坛管理相关的Controller和View文件放到/Areas/Forum下面,以此类推,可以添加诸如会员(Member)、博客(Blog)、邮箱(Email)等多个Areas。各部分都有自己的顶层文件夹,物理文件都分离开来,管理起来比较方便。
  这种方式已经有了很大提高,但是所有的文件还是放在同一个项目里面。当项目规模较大的时候,比较好的开发方式是将不同功能模块按需要独立到不同项目里面,最后再整合成一个整体。这样,每一个项目可以独立开发、测试和发布。

第二次改进

  以项目的形式添加会员(Member)模块:
  1. 在解决方案上面新建一个MvcDemo.Member的MVC4项目,并且删除Global.asax和Web.config两个文件
  2. 在根目录新建一个MemberAreaRegistration.cs,输入如下内容(无需指定namespace):
  

public class MemberAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get { return "Member"; }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "Member_default",
            "Member/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }
        );
    }
}

3、在MvcDemo.Member项目的Controllers文件夹中新建HomeController.cs控制器。
4、在MvcDemo项目中添加会员(Member)Areas,在Views文件夹中添加Home文件夹,并在Home文件夹中新建Index.cshtml,删掉自动生成的MemberAreaRegistration.cs文件。
5、在MvcDemo项目中引用MvcDemo.Member项目。
现在运行程序并访问localhost/Forum/Home/Index可以发现Forum项目生效了。这样,我们可以将所有的与后台管理相关的Controller都放到这个新的项目中来。
但是很快你会发现,一个新的“问题”又出现了:
当你在MvcDemo.Member里面的HomeController添加新的Action(例如:Add),然后习惯性在上面右键-“Add View”后,你会发现新增的Add.cshtml文件出现在MvcDemo.Member/Views/Home下面,然后当你运行程序访问localhost/Member/Home/Add的时候,浏览器返回的却是:localhost/Home/Add,原来路由只会在主程序MvcDemo的对应目录中寻找View。这么一来,MVC框架提供给我们的脚手架功能就大打折扣,当然你可以手动在MvcDemo/Areas/Member/Views中添加对应的View,或者在MvcDemo.Member项目中自动生成了View之后再拷贝过去。有没有更好的办法呢?

第三次改进

为了使我们在MvcDemo.Member自动生成的View自动同步到MvcDemo/Areas/Member/Views文件夹中,可以使用“生成事件(Build Event)”里的“后期生成事件命令行(Post-Build Event)”。打开MvcDemo.Member的属性,修改如下图所示:
这里写图片描述
我本地的生成事件为:

mkdir "$(SolutionDir)$(SolutionName)\Areas\Member\Views"
xcopy "$(ProjectDir)Views" "$(SolutionDir)$(SolutionName)\Areas\Member\Views" /S /E /C /Y

意思是完全复制MvcDemo.Member下Views文件夹内所有文件至MvcDemo/Areas/Member/Views中。
现在再次访问/Member/Home/Add就可以得到正确结果了,并且你可以发现Add.cshtml已经被复制到MvcDemo/Areas/Member/Views/Home目录中。
  至此大功告成!我们已经将面向前台和面向后台的模块成功分离到两个独立的项目中,希望能对您有所帮助!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

changuncle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值