本文转自-->王亮的博客文章[ASP.NET MVC 小牛之路]08 - Area 使用

文章引导

MVC路由解析---IgnoreRoute

MVC路由解析---MapRoute

MVC路由解析---UrlRoutingModule

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》

Area的使用的更多相关文章

  1. [转]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 ...

  2. ASP.NET MVC系列:Area

    1. Area简介 ASP.NET MVC Area机制构建项目,可以将相对独立的功能模块切割划分,降低项目的耦合度. 2. Area设置Routing 新建Admin Area后,自动创建Admin ...

  3. Web API项目中使用Area对业务进行分类管理

    在之前开发的很多Web API项目中,为了方便以及快速开发,往往把整个Web API的控制器放在基目录的Controllers目录中,但随着业务越来越复杂,这样Controllers目录中的文件就增加 ...

  4. MVC View中获取action、controller、area名称

    获取控制器名称: ViewContext.RouteData.Values["controller"].ToString(); 获取Action名称: ViewContext.Ro ...

  5. [LeetCode] Rectangle Area 矩形面积

    Find the total area covered by two rectilinear rectangles in a2D plane. Each rectangle is defined by ...

  6. 如何在Linux上使用文件作为内存交换区(Swap Area)

    交换区域(Swap Area)有什么作用? 交换分区是操作系统在内存不足(或内存较低)时的一种补充.通俗的说,如果说内存是汽油,内存条就相当于油箱,交换区域则相当于备用油箱. Ubuntu Linux ...

  7. MVC 添加Area

    在MVC项目中经常会使用到Area来分开不同的模块让项目结构更加的清晰. 步骤如下: 项目 –> 添加 -> 区域 ( Area ) 输入 Admin 添加成功后 Area包含: 创建一个 ...

  8. ASP.NET MVC 设置Area中 Controller 的方法 默认启动页

    MVC中通常分区域编程,互不干扰,如果需要设置某个区域下面的某个控制器下面的某个方法为默认启动页的话,直接修改项目的路由如下: public static void RegisterRoutes(Ro ...

  9. [ASP.NET MVC 小牛之路]08 - Area 使用

    ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,每个Area代表应用程序的不同功能模块.这对于大的工程非常有用,Area 使每个功能模块都有各自的文件夹,文件夹中有自己的Cont ...

  10. ASP.Net MVC Action重定向跳出Controller和Area

    1.重定向方法简介 [HttpPost] public ActionResult StudentList( string StudName, string studName, DateTime Bir ...

随机推荐

  1. javascript获取网页宽高,屏幕宽高,屏幕分辨率等

    ​ <script> var s = ""; s += "\r\n网页可见区域宽:"+ document.body.clientWidth; s + ...

  2. Cocos2d-x之Label

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. 在游戏开发中经常会使用标签文字,例如,游戏介绍,玩家积分,菜单选项,文字提示等等.      LabelTTF 直接支持使用 TTF 字库 ...

  3. SpringBoot连接Oracle

    pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...

  4. 北京邀请赛 B. Beautiful Garden

    题意:给你坐标和n个点,求最少移动的点使得n个点成等差数列 思路:既然要成等差数列,那么最起码有两个点是不动的,然后枚举这两个点中间的点的个数,近期水的要死,看了队友的代码做的 #include &l ...

  5. MariaDB学习笔记(二)

    七 索引索引:索引是创建在表上的,是对数据库表中的一列或多列的值进行排序的一种结构.索引可以提高查询的速度.索引有两种存储类型: B型树索引 哈希索引I nnoDB和MyISAM支持B型树索引,MEM ...

  6. 获取模糊匹配的div id属性

    html中有一批id,以数字+固定字符结尾,前台需要把这一批id组成数组传递给后台 假设固定结尾字符为“pic”,使用 var pidlist=$("[id$='pic']");将 ...

  7. SQL数据库—<8>触发器

    触发器:一.什么是触发器?    一段SQL代码,挂到某个表的某个增.删.改的操作上.    当这个表执行相应的操作时,就会触发这段相应的SQL代码.触发器与存储过程的区别:1.存储过程是独立于表存在 ...

  8. Ubuntu14.04搭建Boa服务

    1. 下载 boa 源码 : https://sourceforge.net/projects/boa/ 版本:boa-0.94.13.tar.gz 2. 在Ubuntu 下解压进入 [boa-0.0 ...

  9. docker 安装cat

    1.下载cat cat 地址:https://github.com/dianping/cat 进入opt 创建cat文件夹 cd /opt/ mkdir cat cd cat 下载cat git cl ...

  10. mysql创建用户账号出错

    在数据库中输入“create user 'tom'@'%' identified by '123456';”时,出现“ERROR 1819 (HY000): Your password does no ...