MVC中实现Area几种方法
概述
ASP.NET MVC中,是依靠某些文件夹以及类的固定命名规则去组织model实体层,views视图层和控制层的。如果是大规模的应用程序,经常会由不同功能的模块组成,而每个功能模块都由MVC中的三层所构成,因此,随着应用程序规模的增大,如何组织这些不同功能模块中的MVC三层的目录结构,有时对开发者来说显得是种负担。所幸,MVC提供了Area机制,让开发人员可以对项目实现模块的管理。
Area就是严格的按照MVC的规定对文件目录结构和类的命名规则进行命名。我以社交网站的开发为例,主要介绍下如何实现自定义Area。
Default Area
如社交网站一般会包括微博,贴吧,群组,资讯等主要的模块。采用MVC的Area机制实现开发,我们只要为项目添加4个Area即可,如图所示:
Custom Area
自定义Area的实现主要有两种方式。
1. 借助Default Area。
a.在SNS Solution中添加一个新的MVC项目Group,关键点是要将新项目的位置保存在SNS项目的Areas目录下。
b.删除Group项目下的Web.config和Global.asax文件。
c.在Group项目下添加类文件GroupAreaRegistration.cs,该类继承AreaRegistration,并重写AreaName属性和RegisterArea方法。
d.在SNS中添加对Group的引用。
2. 完全自定义实现。
所谓完全自定义就是对模块的添加位置不再一味的要求到Areas目录下,而是开发人员指定的某个目录。
所以我们可以在SNS项目中添加以各新的目录Applications。并在该目录下添加新的MVC项目,
删除项目下的Web.config和Global.asax文件and添加类文件GroupAreaRegistration.cs,该类继承AreaRegistration,并重写AreaName属性和RegisterArea方法。
添加引用到SNS。到这里之前的基本一样。主要区别就在这里了,先说下实现,然后会对原理进行下分析。
1. 在SNS项目中添加一个如下的类。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace MvcApplication1 { public class RazorEngine : RazorViewEngine { public RazorEngine() { base.AreaViewLocationFormats = new string[]{ "~/Applications/{2}/Views/{1}/{0}.cshtml" }; base.AreaPartialViewLocationFormats = new string[]{ "~/Applications/{2}/Views/{1}/{0}.cshtml" }; base.AreaMasterLocationFormats = new string[]{ "~/Applications/{2}/Views/{1}/{0}.cshtml" }; } public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) { string area = GetAreaName(controllerContext.RouteData); controllerContext.RouteData.DataTokens["area"] = area; return base.FindView(controllerContext, viewName, masterName, useCache); } public string GetAreaName(RouteBase route) { IRouteWithArea routeWithArea = route as IRouteWithArea; if (routeWithArea != null) { return routeWithArea.Area; } Route route2 = route as Route; if (route2 != null && route2.DataTokens != null) { return route2.DataTokens["area"] as string; } return null; } public string GetAreaName(RouteData routeData) { object obj; if (routeData.DataTokens.TryGetValue("area", out obj)) { return obj as string; } if (GetAreaName(routeData.Route) == null) { routeData.Values.TryGetValue("area", out obj); } return obj as string; } } }
最后在SNS的修改Global.asax。如下:
重要的一点就是要把新添加的mvc的项目生成dll的的位置指向根目录下的bin。