Area 使用
ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,每个Area代表应用程序的不同功能模块。这对于大的工程非常有用,Area 使每个功能模块都有各自的文件夹,文件夹中有自己的Controller、View和Model,但对于管理也增加了一定的难度。
本文目录
创建Area
右键工程选择 添加->区域,弹出如下填写Area的对话框:

点击添加后,工程目录结构如下:

和创建一个空MVC工程结构类似,Admin Area 有自己的 Controllers、Models 和 Views 文件夹,不一样的地方就是多了一个 AdminAreaRegistration.cs 文件,这个文件中定义了一个叫 AdminAreaRegistration 的类,它的内容如下:
namespace MvcApplication1.Areas.Admin {
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 }
);
}
}
}
系统自动生成的 AdminAreaRegistration 类继承至抽象类 AreaRegistration,并重写了 AreaName 属性和 RegisterArea 方法。在 RegisterArea 方法中它为我们定义了一个默认路由,我们也可在这个方法中定义专属于Admin Area的的其他路由。但有一点要注意,在这如果要给路由起名字,一定要确保它和整个应用程序不一样。
AreaRegistrationContext 类的 MapRoute 方法和 RouteCollection 类的 MapRoute 方法的使用是一样的,只是 AreaRegistrationContext 类限制了注册的路由只会去匹配当前 Area 的 controller,所以,如果你把在 Area 中添加的 controller 的默认命名空间改了,路由系统将找不到这个controller 。
RegisterArea 方法不需要我们手动去调用,在 Global.asax 中的 Application_Start 方法已经有下面这样一句代码为我们做好了这件事:
protected void Application_Start() {
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
调用 AreaRegistration.RegisterAllAreas 方法让MVC应用程序在启动后会寻找所有继承自 AreaRegistration 的类,并为每个这样的类调用它们的 RegisterArea 方法。
注意:不要轻易改变 Application_Start 中注册方法的顺序,如果你把RouteConfig.RegisterRoutes方法放到AreaRegistration.RegisterAllAreas方法之前,Area 路由的注册将会在路由注册之前,路由系统是按顺序来匹配的,所以这样做会让请求 Area 的 Controller 匹配到错误的路由。
Area的运行
在Area中添加controller、view和model和一般的添加是一样的。在这,我们在Admin Area中添加一个名为 Home 的controller,代码如下:
public class HomeController : Controller {
public ActionResult Index() {
return View();
}
}
然后我们再为Index Acton添加一个View,代码如下:
@{
ViewBag.Title = "Index";
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
<h2>Admin Area Index</h2>
</div>
</body>
</html>
运行应用程序,然后将URL定位到/Admin/Home/Index,下面是运行结果:

到这,我们已经看到,Area中的的工作流程其实就是和根目录下的流程是一样的。但Area并不是一个完全独立的工作空间,我们下面来看看。
Controller的歧义问题
试想一下,如果我们现在在根目录的 Controller 文件夹中也添加一个名为 Home 的 Controller,然后我们通过把URL定位到 /Home/Index,路由系统能匹配到根目录下的 Controller 吗?
在根目录的 Controllers 文件夹中添加好 HomeController 后,为Index添加View,内容随意:
...
<body>
<div>
<h2>Root Index</h2>
</div>
</body>
...
路由不改动,我们使用 RouteConfig.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 }
);
}
运行程序,将URL定位到 /Home/Index。结果我们会看到如下错误信息:

出现这个问题是因为路由系统进行匹配的时候出现了Controller同名的歧义。
当Area被注册的时候,Area中定义的路由被限制了只寻找 Area 中的Controller,所以我们请求 /Admin/Home/Index 时能正常得到 MvcApplication1.Areas.Admin.Controllers 命名空间的 HomeController。然而我们在RouteConfig.cs文件的RegisterRoutes方法中定义的路由并没有类似的限制。
为了解决这个问题,我们需要在RouteConfig.cs文件中定义的路由中加上对应的 namespaces 参数。RouteConfig.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[] { "MvcApplication1.Controllers" }
);
}
运行程序,如下结果说明解决了同名歧义问题:

添加了 namespaces 参数后,路由系统在对这个路由进行匹配时,优先匹配指定命名空间的controller,如果匹配到则即刻停止查找,如果在指定的命名空间下没有匹配到对应的controller,再按照一般的方式进行匹配。
生成Area URL链接
关于Area的URL链接生成,可以分为这么三种情况:第一种是在当前Area生成指向当前Area的链接;第二种是生成指向其他Area的链接;第三种是在某个Area中生成指向根目录的链接。下面是这三种情况生成链接的方法,使用的路由定义是系统默认的。
如果要在Area中生成当前Area的URL链接,直接用下面的方法就行:
@Html.ActionLink("Click me", "About")
它根据当前所在的Area和Controller会生成如下Html代码:
<a href="/Admin/Home/About">Click me</a>
如果要生成其他Area的URL链接,则需要在Html.ActionLink方法的匿名参数中使用一个名为area的变量来指定要生成链接的Area名称,如下:
@Html.ActionLink("Click me to go to another area", "Index", new { area = "Support" })
它会根据被指定的Area去找路由的定义,假定在Support Area中定义了对应的路由,那么它会生成如下链接:
<a href="/Support/Home/Index">Click me to go to another area</a>
如果要在当前Area生成指根目录某个controller的链接,那么只要把area变量置成空字符串就行,如下:
@Html.ActionLink("Click me to go to top-level part", "Index", new { area = "" })
它会生成如下Html链接:
<a href="/Home/Index">Click me to go to top-level part</a>
参考:《Pro ASP.NET MVC 4 4th Edition》
作者:Liam Wang
出处:http://www.cnblogs.com/willick/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如有问题或建议,请多多赐教,非常感谢。
Area 使用的更多相关文章
- [转]NopCommerce How to add a menu item into the administration area from a plugin
本文转自:http://docs.nopcommerce.com/display/nc/How+to+code+my+own+shipping+rate+computation+method Go t ...
- ASP.NET MVC系列:Area
1. Area简介 ASP.NET MVC Area机制构建项目,可以将相对独立的功能模块切割划分,降低项目的耦合度. 2. Area设置Routing 新建Admin Area后,自动创建Admin ...
- Web API项目中使用Area对业务进行分类管理
在之前开发的很多Web API项目中,为了方便以及快速开发,往往把整个Web API的控制器放在基目录的Controllers目录中,但随着业务越来越复杂,这样Controllers目录中的文件就增加 ...
- MVC View中获取action、controller、area名称
获取控制器名称: ViewContext.RouteData.Values["controller"].ToString(); 获取Action名称: ViewContext.Ro ...
- [LeetCode] Rectangle Area 矩形面积
Find the total area covered by two rectilinear rectangles in a2D plane. Each rectangle is defined by ...
- 如何在Linux上使用文件作为内存交换区(Swap Area)
交换区域(Swap Area)有什么作用? 交换分区是操作系统在内存不足(或内存较低)时的一种补充.通俗的说,如果说内存是汽油,内存条就相当于油箱,交换区域则相当于备用油箱. Ubuntu Linux ...
- MVC 添加Area
在MVC项目中经常会使用到Area来分开不同的模块让项目结构更加的清晰. 步骤如下: 项目 –> 添加 -> 区域 ( Area ) 输入 Admin 添加成功后 Area包含: 创建一个 ...
- ASP.NET MVC 设置Area中 Controller 的方法 默认启动页
MVC中通常分区域编程,互不干扰,如果需要设置某个区域下面的某个控制器下面的某个方法为默认启动页的话,直接修改项目的路由如下: public static void RegisterRoutes(Ro ...
- [ASP.NET MVC 小牛之路]08 - Area 使用
ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,每个Area代表应用程序的不同功能模块.这对于大的工程非常有用,Area 使每个功能模块都有各自的文件夹,文件夹中有自己的Cont ...
- ASP.Net MVC Action重定向跳出Controller和Area
1.重定向方法简介 [HttpPost] public ActionResult StudentList( string StudName, string studName, DateTime Bir ...
随机推荐
- javascript 中的location.pathname
1 location.pathname; 这在之前我没怎么注意过,所以研究研究.location.pathname:返回URL的域名(域名IP)后的部分.例如 http://www.joymood.c ...
- crawler_解析之_jquery_语法选择器使用方法
爬虫解析一般使用 正则或者给予样式的 jquery语法选择器 正则是根本,类比jsoup基于dom,底层也有部分是基于正则实现的,linux操作系统 文本处理也是借助强大的正则体现的 .关于正则 请参 ...
- CSS hack 如何区分所有IE浏览器和非IE浏览器
网上方法很多,例如,测试后得出以下结论,多余的话不说了,直入主题: 1.所有的推理IE浏览器 正解:此写法仅仅被lE浏览器识别,非IE浏览器不识别. <!--[if IE]> <st ...
- js小记 function 的 length 属性
原文:js小记 function 的 length 属性 [1,2,3]., ,这个略懂js的都知道. 但是 eval.length,RegExp.length,"".toStr ...
- sql server 视图 的一个例子
这是一个 有点复杂的查询.我现在 想把他封装 成 视图 其中 B.RecordID= 41 提供给 视图外查询. create view view_UserRecord as select Rec ...
- Swift语言指南(八)--语言基础之元组
原文:Swift语言指南(八)--语言基础之元组 元组 元组(Tuples)将多个值组合为一个复合值.元组内的值可以是任何类型,各个元素不需要为相同类型(各个元素之间类型独立,互不干扰--Joe.Hu ...
- ASP.NET学习笔记--自己写的Login.aspx
以前有大学有学过,但是没学好,现在准备完全自己动手做一个网站,学习一下ASP.NET 做一个登录页面,首先要有创建一个新的网站,添加Login.aspx,然后做出自己想要的DIV和CSS布局, 之后创 ...
- BZOJ 3282 Tree Link-Cut-Tree(LCT)
题目大意: 给定N个点以及每一个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y ...
- 玩转Web之servlet(四)---B/S是怎样使用http协议完毕通信过程的
在上一篇文章中,我简单的说了一下B/S架构的流程图,关于浏览器和server之间的通信过程知识含糊的说了一下,在这篇文章中我再总结一下B/S架构里是怎样利用http协议去完毕通信的. (一)通讯过程 ...
- 一个完整的Installshield安装程序实例—艾泽拉斯之海洋女神出品(四) --高级设置二
原文:一个完整的Installshield安装程序实例-艾泽拉斯之海洋女神出品(四) --高级设置二 上一篇:一个完整的安装程序实例—艾泽拉斯之海洋女神出品(三) --高级设置一4. 根据用户选择的组 ...