`

[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 文件,这个文件中定义了一个叫 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 小牛之路] 文章系列

    八、[ASP.NET MVC 小牛之路]08 - Area 使用 九、[ASP.NET MVC 小牛之路]09 - Controller 和 Action (1) 十、[ASP.NET MVC 小牛之路]10 - Controller 和 Action (2) 十一、[ASP.NET MVC 小牛之路]11 - Filter 十二...

    黄宝翕-ASP.NET MVC4开发指南

    高清扫描版的《ASP.NET MVC4开发指南》(黄保翕著),比较偏重理论,知识深度较浅,适合初学MVC的同学阅读。 1.在学习ASP.NETMVC之前 2.创建正确的开发观念 3.新手上路初体验 4.Routing与ASP.NET生命周期 5.Model相关...

    Asp.net Mvc 关于area的一个小模型

    Asp.net Mvc 关于area的一个小模型 非常基础,提供给mvc初学者

    asp.net mvc

    The string “area” in Route values now has special meaning in ASP.NET MVC, in the same way that “controller” and “action” do. One implication is that if ...

    ASP.NET MVC中设置跨域访问问题

    主要介绍了ASP.NET MVC中设置跨域访问问题,需要的朋友可以参考下

    MvcContrib分离ASP.NET MVC项目源码2012612

    MvcContrib分离ASP.NET MVC项目源码 项目描述 在ASP.NET MVC复杂项目的开发中,随着项目规模的扩大,我们可能需要对不同模块按需进行分离。 MvcContrib(Portable Area)可以将一个MVC项目里的所有内容(包括Views,...

    ASP.NET MVC 使用二级域名来注册Area区域

    用routing engine (System.Web.Routing) 来自动注册区域以实现多个Views

    ModularVNext:在ASP.NET MVC 6中使用单独的模块项目进行示例探索

    该项目演示了几种在ASP.NET MVC 6项目中封装功能包的方法。 也就是说,允许将ASP.NET MVC 6功能的模块编写在与主应用程序不同的项目中。 该样本的目标是减少开发和部署时的摩擦。 在开发时,需要使用磁盘上的文件以...

    MVC2.0项目模板 版本0.1源码

    MVC2.0项目模板 版本0.1源码 ...MVC 2.0 Area 主题 EF 4.0 缓存 EF 4.0 日志 分页 Jquery UI Jquery Layout 等等 本例子仅仅涉及到一些基本的功能,您可以随意扩充和使用,基本的操作方法都已覆盖。

    FeaturesMvc:为 ASP.NET MVC 启用基于功能的项目结构

    FeaturesMvc为 ASP.NET MVC 启用基于功能的项目结构。 它目前由2个项目组成。 FeaturesMvc允许从 features 文件夹中解析视图。 FeaturesMvc.Bundling可以轻松地将 javascript、CSS 等从包中的功能文件夹中包含在内...

    WebApiSwaggerJWT

    基于ASP.NET的MVC构建WebAPI,以Swagger作为说明文档和测试的界面,用JWT作为票据,内部采用HS256加密算法。

    EasyCMSPracticeWebsite:使用ASP.NET(C#) MVC 之简易CMS 练习网站

    EasyCMSPracticeWebsite 使用ASP.NET(C#) MVC 之简易CMS 练习网站 这是一个简易的CMS练习网站,仅...使用技术&gt; -ASP.NET MVC(C#) 网站范本(升级至5.2.3) -会员登入使用范本预设Identity 1.0 -使用Area 区分Admin 后台

    NopCommerce (ASP.NET商城) v2.0.zip

    Moved to ASP.NET MVC 3.0 (Razor syntax) Really pluggable architecture (just drop a plugin to the /plugins folder in your nopCommerce directory) SQL Server Compact support Code-First Development ...

    NopCommerce (ASP.NET商城) v2.0 源码包.zip

    Moved to ASP.NET MVC 3.0 (Razor syntax) Really pluggable architecture (just drop a plugin to the /plugins folder in your nopCommerce directory) SQL Server Compact support Code-First Development ...

    CodematicDemoMVC

    2009年3月 asp.net mvc1发布,缺失Area等关键技术 2010年3月12日: 强类型的HTML Helper数据验证,自定义模板,Area,异步Controller .Net4的技术:dynamic类型,默认值的方法参数 Why ASP.Net MVC3 asp.net 视图...

    MVC学习资料

    标题: 大叔手记(14):利用Routing特性提高ASP.NET MVC3站点的SEO权重 ? - 汤姆大叔 2011-12-23 14:21 阅读:296 - 评论:5 查看评论 发表评论 返回 简介 我们在开发互联网程序的时候,有个很重要的事情就是做搜索...

    Webdiyer.AspNetCore.MvcCorePager分页控件改进版

    实现分页大小切换,跳转页,总记录数显示。

    Sprint12_Tasks:Sprint12任务

    Sprint12_Tasks Sprint12任务任务创建一个ASP.Net Core MVC应用程序,该应用程序对三角形执行适当的计算。 以自己的方式设计所有类和方法。 该应用程序应处理以下请求: 以如下形式显示有关三角形的信息: ---------...

Global site tag (gtag.js) - Google Analytics