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>

[ASP.NET MVC 小牛之路]08 - Area 使用相关推荐

  1. [ASP.NET MVC 小牛之路]10 - Controller 和 Action (2)

    继上一篇文章之后,本文将介绍 Controller 和 Action 的一些较高级特性,包括 Controller Factory.Action Invoker 和异步 Controller 等内容. ...

  2. [ASP.NET MVC 小牛之路]16 - Model 验证

    上一篇博文 [ASP.NET MVC 小牛之路]15 - Model Binding 中讲了MVC在Model Binding过程中如何根据用户提交HTTP请求数据创建Model对象.在实际的项目中, ...

  3. [ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject

    特别提醒:本文编写时间是 2013 年,请根据目前 .NET 发展接收你所需的知识点. 为什么需要依赖注入 在[ASP.NET MVC 小牛之路]系列的理解MVC模式文章中,我们提到MVC的一个重要特 ...

  4. [ASP.NET MVC 小牛之路]11 - Filter

    Filter(筛选器)是基于AOP(面向切面编程)的设计,它的作用是对MVC框架处理客户端请求注入额外的逻辑,以非常简单优美的方式实现横切关注点(Cross-cutting Concerns).横切关 ...

  5. [ASP.NET MVC 小牛之路]01 - 理解MVC模式

    特别提醒:本文编写时间是 2013 年,请根据目前 .NET 发展接收你所需的知识点. PS:MVC出来很久了,工作上一直没机会用.出于兴趣,工作之余我将展开对MVC的深入学习,通过博文来记录所学所得 ...

  6. [ASP.NET MVC 小牛之路]02 - C#知识点提要

    特别提醒:本文编写时间是 2013 年,请根据目前 .NET 发展接收你所需的知识点. 本篇博文主要对asp.net mvc开发需要撑握的C#语言知识点进行简单回顾,尤其是C# 3.0才有的一些C#语 ...

  7. 【ASP.NET MVC 学习笔记】- 09 Area的使用

    本文参考:http://www.cnblogs.com/willick/p/3331519.html 1.ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,这对于大的工程非常有用, ...

  8. ASP.NET MVC 学习之路-3

    本文在于巩固基础 到这里不得不说ASP.NET MVC一个规则:惯例优先原则 ASP.NET会假定开发人员遵循特定的规则来构建自己的程序而不是使用配置文件 ASP.NET MVC文件夹结构也遵循惯例优 ...

  9. Asp.net MVC 学习之路-003(增删改查,后端手工,前端生成)

    时间:2017-03-09 Asp.net Mvc实现增删改查 1, 创建数据库 可参考我写的EntityFramework实现过程:http://www.jianshu.com/nb/1016674 ...

  10. ASP.NET MVC 学习之路-4

    本文在于巩固基础 模型绑定 从URL 获取值 public ActionResult About(int id){ViewBag.Id = id;return View();} @{ViewBag.T ...

最新文章

  1. webpack4升级指北
  2. “4K云字库”基本框架图
  3. 探究Java如何实现原子操作(atomic operation)
  4. QT事件的接受与忽略
  5. php软件开发--linux进阶
  6. spss典型相关分析_SPSS做典型相关分析,新版本软件已经有独立菜单模块可完成...
  7. python3 tkinter 实现凯撒密码GUI界面
  8. oracle的varchar用法,以VARCHAR2作为key的索引表的使用
  9. 人工智能培训机构-光环国际,开课吧,贪心学院,交大,黑马,七月在线,咕泡,百战程序员哪个靠谱?
  10. 计算机项目答辩评分标准,课题答辩评分标准是什么
  11. 17美亚团队赛电子取证
  12. html 图片靠左浮动,float【css浮动】left靠左 right靠右属性图文教程
  13. armbian开启ssh_armbian笔记
  14. 剪枝计算机,α-β剪枝 - 电脑黑白棋 - 黑白棋天地
  15. 可视化展示——论文相似度分析页面设计
  16. TDengine学习笔记
  17. 低速 CAN 总线偶尔无法正常通信,该如何诊断?
  18. 移动用户和运营商的签约速率
  19. 租房项目 获取地区信息服务
  20. Web3D虚拟人捏脸

热门文章

  1. 【数字信号】基于matlab GUI DTMF双音多频电话拨号仿真【含Matlab源码 805期】
  2. 【疾病分类】基于matlab SVM农作物叶子虫害识别与分类【含Matlab源码 624期】
  3. MATLAB如何生成scr文件,基于matlab生成的scr文件,实现autocad曲线绘制,代码问题...
  4. linux搭建vsftp服务器_Linux(CentOS 7)搭建VSFTP服务器
  5. 创建dqn的深度神经网络_深度Q网络(DQN)-III
  6. numpy常用的一种高效切片方式
  7. python的标准数据类型_Python中的标准数据类型
  8. upupoo怎么设置本地html文件,关于Upupoo自定义元素教程
  9. php v9视频教程,PHPCMS V9二次开发视频教程全集
  10. mysql bytes sent_zabbix企业应用之监控3306端口的mysql