ASP.NET MVC- 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>

  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,再按照一般的方式进行匹配。

  

  参考文章:http://www.cnblogs.com/willick/p/3331519.html

时间: 2024-09-30 10:20:17

ASP.NET MVC- Area 使用的相关文章

ASP.NET MVC Area使用-将Area设置成独立项目

环境说明:Vistual Studio 2013 MVC 4.0 其实关于ASP.NET MVC Area使用的基础知识可以参考 http://www.cnblogs.com/willick/p/3331519.html 这篇软文. Global.asax 中的 Application_Start 方法里面有这样一句代码 AreaRegistration.RegisterAllAreas(); 估计: 它的作用会到当前MVC 所在的bin中动态注入继承了 AreaRegistration的类,

ASP.NET MVC Area 的使用

MVC提供Area机制,在同一个项目之内就能够切割出不同的ASP.NET MVC网站. 插入:首先在相同的位置,比如说同一个文件夹(如:Controllers)是不能创建俩个相同名称的文件(如:HomeController),其次在不同的文件夹中如fold1和fold2,中各自创建一个TestController,程序能够通过编译,但当浏览器视图执行/Test时,网站报出异常,如图: 因为在默认情况下,路由会同时匹配两个controller,造成无法访问. 在项目上,右键,创建区域,问题解决.

ASP.NET MVC系列:Area

1. Area简介 ASP.NET MVC Area机制构建项目,可以将相对独立的功能模块切割划分,降低项目的耦合度. 2. Area设置Routing 新建Admin Area后,自动创建AdminAreaRegistration.cs,用于设置Area Routing. using System.Web.Mvc; namespace Libing.Portal.Web.Areas.Admin { public class AdminAreaRegistration : AreaRegistr

MVC Area Usage

ASP.NET MVC Area操作 新建 Area:右键 -> Add –> Area 继承 AreaRegistration,重写AreaName属性与RegisterArea方法 public class BookStudyAreaRegistration : AreaRegistration { public override string AreaName { get { return "BookStudy"; } } public override void R

ASP.NET MVC使用Areas后怎样获取Area(区域)的名称

写此随笔,目的只为今后在ASP.NET MVC项目中再用到Area(区域)时作为备查. 获取当前Area(区域)名称的方法是: ViewContext.RouteData.DataTokens["area"] 这样,我就可以通过下面三个语句,分别获取用户当前访问的Area.Controller和Action string areaName = filterContext.RouteData.DataTokens["area"] == null ? "&qu

Asp.net MVC 4新项目中创建area的后续操作

Asp.net MVC 4新项目中创建area后,往往HomeController与area的HomeController路由发生混淆,需要手工设置一些地方避免mvc无法识别默认路由的状况. 无废话具体步骤: 1. 检查早Global.asax和\App_Start\RouteConfig.cs中是否已经自动添加了AreaRegistration.RegisterAllAreas();如不存在,进入第2步,否则第3步 2. 在\App_Start\RouteConfig.cs中,添加AreaRe

asp.net mvc 4多级area实现技巧

今天在工作要实现这个多级area.其原因是这个项目需要多级的功能,大的类别里有小的类别,小的类别里有具体的功能项,每一个功能项还有若干动作Action,所以在菜单和mvc工程的结构上都需要有体现多级的元素,菜单是用的accordion,每一个大类就是accordion的一个pane,然后每一个小类就是用一个表格来表示的,每一个功能就是用单元格加一个链接来表示的.在网站目录结构上,area可以很方便地实现一级的目录结构,比如可以有admin, backoffice, logging, busine

Asp.net MVC 基于Area的路由映射

对于一个较大规模的Web应用,我们可以从功能上通过Area将其划分为较小的单元.每个Area相当于一个独立的子系统,具有一套包含Models.Views和Controller在内的目录结构和配置文件.一般来说,每个Area具有各自的路由规则(URL模版上一般会体现Area的名称),而基于Area的路由映射通过AreaRegistration进行注册. 一.创建Areas 右键工程 -> 添加->区域 添加后生成一套包含Models.Views和Controller在内的目录结构和配置文件:只是

asp.net mvc多级目录结构和多级area实现技巧

今天在工作要实现这个多级area.其原因是这个项目需要多级的功能,大的类别里有小的类别,小的类别里有具体的功能项,每一个功能项还有若干动作Action,所以在菜单和mvc工程的结构上都需要有体现多级的元素,菜单是用的accordion,每一个大类就是accordion的一个pane,然后每一个小类就是用一个表格来表示的,每一个功能就是用单元格加一个链接来表示的.在网站目录结构上,area可以很方便地实现一级的目录结构,比如可以有admin, backoffice, logging, busine

Asp.Net MVC 插件化开发简化方案

Web 管理系统可以庞大到不可想像的地方,如果想就在一个 Asp.Net MVC 项目中完成开发,这个工程将会变得非常庞大,协作起来也会比较困难.为了解决这个问题,Asp.Net MVC 引入了 Areas 的概念,将模块划分到 Area 中去--然而 Area 仍然是主项目的一部分,多人协作的时候仍然很容易造成 .csproj 项目文件的冲突. 对于这类系统,比较好的解决办法是采用 SOA 的方式,把一个大的 Web 系统划分成若干微服务,通过一个含授权中心的 Web 集散框架组织起来.不过这