Area 使用

时间:2023-03-09 03:17:32
Area 使用

ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,每个Area代表应用程序的不同功能模块。这对于大的工程非常有用,Area 使每个功能模块都有各自的文件夹,文件夹中有自己的Controller、View和Model,但对于管理也增加了一定的难度。

本文目录

创建Area

右键工程选择 添加->区域,弹出如下填写Area的对话框:

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中的的工作流程其实就是和根目录下的流程是一样的。但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。结果我们会看到如下错误信息:

Area 使用

出现这个问题是因为路由系统进行匹配的时候出现了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" }
);
}

运行程序,如下结果说明解决了同名歧义问题:

Area 使用

添加了 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/

联系:liam.wang@outlook.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如有问题或建议,请多多赐教,非常感谢。

【01】 ASP.NET MVC 小牛之路 
[ASP.NET MVC 小牛之路]08 - Area 使用
摘要: ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,每个Area代表应用程序的不同功能模块。这对于大的工程非常有用,Area使每个功能模块都有各自的文件夹,文件夹中有自己的Controller、View和Model,但对于管理也增加了一定的难度。本文目录创建Area右键工程选择 添加->区域,弹出如下填写Area的对话框:点击添加后,工程目录结构如下:和创建一个空MVC工程结构类似,Admin Area有自己的 Controllers、Models 和 Views 文件夹,不一样的地方就是多了一个AdminAreaRegistration.cs 文件,这个文件中定义了一阅读全文
posted @ 2013-10-02 20:35 Liam Wang 阅读(572) | 评论 (1) 编辑
[ASP.NET MVC 小牛之路]07 - URL Routing
摘要: 我们知道在ASP.NET Web Forms中,一个URL请求往往对应一个aspx页面,一个aspx页面就是一个物理文件,它包含对请求的处理。而在ASP.NET MVC中,一个URL请求是由对应的一个Controller中的Action来处理的,由URL Routing来告诉MVC如何定位到正确的Controller和Action。笼统的讲,URL Routing包含两个主要功能:解析URL 和生成URL,本文将围绕这两个大点进行讲解。本文目录URL Routing 的定义方式让我们从下面这样一个简单的URL开始:http://mysite.com/Admin/Index在域名的后面,默认使用阅读全文
posted @ 2013-09-28 23:32 Liam Wang 阅读(1192) | 评论 (10) 编辑
[ASP.NET MVC 小牛之路]06 - 使用 Entity Framework Code First
摘要: 在家闲着也是闲着,继续写我的[ASP.NET MVC 小牛之路]系列吧。在该系列的上一篇博文中,在显示书本信息列表的时候,我们是在程序代码中手工造的数据。本文将演示如何在ASP.NET MVC中使用Entity Framework Code First从数据库中获取数据。虽然本文题目听上去比较简单,但如果你认真阅读,相信你一定会有所收获。本文目录:ORM 和 EF当我们要开发一个应用程序,就要考虑怎样展示数据,怎样持久化数据。考虑这个问题时我们所要关心的东西,最重要的莫过于程序的性能、开发的简易性和代码的可维护、可扩展性。持久化(Persistence),是指在应用程序中能永久地保存各个处理状阅读全文
posted @ 2013-09-07 19:41 Liam Wang 阅读(946) | 评论 (9) 编辑
[ASP.NET MVC 小牛之路]05 - 使用 Ninject
摘要: 在[ASP.NET MVC 小牛之路]系列上一篇文章(依赖注入(DI)和Ninject)的末尾提到了在ASP.NET MVC中使用Ninject要做的两件事情,续这篇文章之后,本文将用一个实际的示例来演示Ninject在ASP.NET MVC中的应用。为了更好的理解和撑握本文内容,强烈建议初学者阅读本文前先阅读依赖注入(DI)和Ninject。本文目录:准备工作新建一个名为BookShop的空白解决方案。在该解决方案中分别添加一个名为BookShop.WebUI的MVC空应用程序,和一个名为BookShop.Domain的类库工程。目录结构如下:两个工程添加完后,在BookShop.WebUI阅读全文
posted @ 2013-09-04 11:53 Liam Wang 阅读(1014) | 评论 (6) 编辑
[ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject
摘要: 本文目录:为什么需要依赖注入在[ASP.NET MVC 小牛之路]系列的理解MVC模式文章中,我们提到MVC的一个重要特征是关注点分离(separation of concerns)。我们希望应用程序的各部分组件尽可能多的相互独立、尽可能少的相互依赖。我们的理想情况是:一个组件可以不知道也可以不关心其他的组件,但通过提供的公开接口却可以实现其他组件的功能调用。这种情况就是所谓的松耦合。举个简单的例子。我们要为商品定制一个“高级”的价钱计算器LinqValueCalculator,这个计算器需要实现IValueCalculator接口。如下代码所示:public interface IValue阅读全文
posted @ 2013-08-07 21:37 Liam Wang 阅读(1842) | 评论 (14) 编辑
[ASP.NET MVC 小牛之路]03 - Razor语法
摘要: Razor是MVC3中才有的新的视图引擎。我们知道,在ASP.NET中,ASPX的视图引擎依靠来调用C#指令。而MVC3以后有了一套新的使用@标记的Razor语法,使用起来更灵活更简洁。下面通过一些简单示例让大家快速撑握Razor语法的使用。本文目录准备工作在演示Razor语法的使用之前,我们需要做一些准备工作。1.打开VS创建一个ASP.NET MVC空项目,很简单,就不具体演示了。2.添加一个Model。在项目的Models文件夹中添加一个名为Product的类。在这我们把前一篇C#知识点提要用到的Product类搬过来用。代码如下:namespace MvcApplication1.Mo阅读全文
posted @ 2013-08-02 14:39 Liam Wang 阅读(1453) | 评论 (6) 编辑
[ASP.NET MVC 小牛之路]02 - C#知识点提要
摘要: 本篇博文主要对asp.net mvc开发需要撑握的C#语言知识点进行简单回顾,尤其是C# 3.0才有的一些C#语言特性。对于正在学asp.net mvc的童鞋,不防花个几分钟浏览一下。本文要回顾的C#知识点有:特性、自动属性、对象集合初始化器、扩展方法、Lambda表达式和Linq查询。C#资深“玩家”可路过。本文目录1.特性(Attributes)特性(Attributes),MSDN的定义是:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型、字段、方法和属性等。Attributes和Microsoft .NET Framework文阅读全文
posted @ 2013-07-25 16:03 Liam Wang 阅读(1784) | 评论 (8) 编辑
[ASP.NET MVC 小牛之路]01 - 理解MVC模式
摘要: PS:MVC出来很久了,工作上一直没机会用,所以我也没去学。出于兴趣,工作之余我将展开对MVC的深入学习,通过博文来记录所学所得,并希望能得到各位园友的斧正。理解一般意义上的MVC模式MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为以下三个基本部分:模型(Model):模型用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。“模型”有对数据直接访问的权力,例如对数据库的访问。“模型”不依赖“视图”和“控制器”,也就是说,模型不关心它会被如何显示或是如何被操作。视图(View):视图能够实现数据有目的的显示。在视图中一般没有程序上的逻阅读全文
posted @ 2013-07-24 17:20 Liam Wang 阅读(1645) | 评论 (1) 编辑