ASP.Net MVC 中配置Route的时候可以设置一个默认的Route。

比如我要在输入http://localhost的时候默认进入http://localhost/home/index。可以在Global.asax中这么配置:

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

很简单,对吧。

但是如果你想把默认值指向一个Area内部的Controller/Action,要怎么做呢?

模仿上面的例子,我是这么做的:

新建一个叫做MyArea的area,然后配置路由如下:

routes.MapRoute(
"Default", // Route name
"{area}{controller}/{action}/{id}", // URL with parameters
new {area = "MyArea", controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

添加了一个area的section,应该可以了吧。

运行一下看看:

结果是Controller冲突,截图如下:

这说明了我们配置的那个{Area}没起作用。原来MVC的route没有对Area进行支持。

来看看MyAreaAreaRegistration的源码中是怎么做的:

public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces) {
if (namespaces == null && Namespaces != null) {
namespaces = Namespaces.ToArray();
} Route route = Routes.MapRoute(name, url, defaults, constraints, namespaces);
route.DataTokens["area"] = AreaName; // disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up
// controllers belonging to other areas
bool useNamespaceFallback = (namespaces == null || namespaces.Length == );
route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback; return route;
}

它在MapRoute的时候加入了一个namespace的约束。那我们也来加上看看。

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new[] { "WebArchDemo.Areas.MyArea.*" }
);

OK,成功了。不过仔细一看。View不对了。它竟然还是去找Area外面的View,而不是这个Area下面的View.

我们在ViewEngine的源码中找一下原因,关键代码是在寻找View时的下面几句:

string areaName = AreaHelpers.GetAreaName(controllerContext.RouteData);
bool usingAreas = !String.IsNullOrEmpty(areaName);
List<ViewLocation> viewLocations = GetViewLocations(locations, (usingAreas) ? areaLocations : null);

ViewEngine会在controllerContext.RouteData中去找AreaName,如果找到的话就用Area中的View,否则用根目录下的View.那这个AreaName是什么时候放如RouteData中的呢?

回头看一下我前面贴出来那段MyAreaAreaRegistration中的源码,关键的一句就是:

就是在注册Area的Route的时候,会把这个AreaName放进去。

明白了这一点,我们就可以来继续改造我们注册route的地方:

         var route =   routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new[] { "WebArchDemo.Areas.MyArea.*" }
); route.DataTokens["area"] = "MyArea";

测试一下,完全正确。

在实际的项目中,可能直接把默认route指向Area内部的一个Action的几率比较小。不过还是有一些特殊场景。

我们通过尝试来实现这么一种特殊场景,分析了AreaRegistration的工作原理,也窥探了一下Route和ViewEngine是如何处理Area的。

我们可以看到,MVC在尽可能少地侵入框架的情况下,实现了一套Area机制。

在ASP.Net MVC 中,如何在Global.asax中配置一个指向Area内部的默认Route的更多相关文章

  1. 如何在Global.asax中判断是否是ajax请求

    今天在一个应用场景中需要在Global.asax中判断一个请求是否是ajax请求,而在ASP.NET MVC中已经提供了一个现成的扩展方法IsAjaxRequest: namespace System ...

  2. 在Asp.Net的Global.asax中Application_Error跳转到自定义错误页无效的解决办法

    在开发Asp.Net系统的时候,我们很多时候希望系统发生错误后能够跳转到一个自定义的错误页面,于是我们经常会在Global.asax中的Application_Error方法中使用Response.R ...

  3. 关于在 ASP.NET 的 Global.asax 中 Application_Error 方法内,设置跳转到自定义错误页无效的问题

    转自:https://www.cnblogs.com/OpenCoder/p/5070645.html 在 Global.asax 中的 Application_Error 方法中,使用 Respon ...

  4. ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则

    原文:ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则 对于Model验证,理想的设计应该是场景驱动的,而不是Model(类型)驱动的,也就是对于同一个Model对象, ...

  5. Asp.Net MVC是否针对每次请求都重新创建一个控制器实例

    一.Asp.Net MVC是否针对每次请求都重新创建一个控制器实例 默认情况下,答案是确定的. ControllerBuilder类 ControllerBuilder.Current用户获取默认的控 ...

  6. Global.asax 中校验Session

    Application 相关的 Application_Init:在每一个HttpApplication实例初始化的时候执行. Application_Disposed:在每一个HttpApplica ...

  7. MVC.Net:通过Global.asax捕捉错误

    在MVC.Net中,如果我们想做一个统一的错误处理的模块,有几个选择,一种是通过一个Base Controller来实现,另外一种就是在Global.asax中实现.这里介绍后一种方法. 首先打开Gl ...

  8. Global.asax中的操作数据库代码无法执行

    本人最近在做一个基于Access数据库的Web应用程序,为了实现一个定时更新数据库的需求,我在Global.asax中的Application_Start函数里写了个计时器, void Applica ...

  9. 定时发布任务,在global.asax中获取文件的物理路径的方法

    如果要把一个相对路径或者虚拟路径映射道服务器的物理路径,通常会使用Server.MapPath()函数,比如将根目录下的html目录映射为物理路径:Server.MapPath("html& ...

随机推荐

  1. Nuget 相关

    1:服务器搭建 1.1:创建空的Web Application 1.2:引用NuGet.Server 包:NuGet.Server 安装完成后的界面 web.config 已经被重写了,里面存在一些配 ...

  2. DIV布局之道三:DIV块的覆盖,DIV层遮盖其他DIV

    DIV布局网页的第三种方式:覆盖.DIV覆盖方式经常应用于网页弹出框的制作,例如在网店系统中,当用户没有登录时,点击购买,系统弹出一个登陆框. 请看代码: HTML部分: XML/HTML Code复 ...

  3. HTML5 <Audio>标签API整理(一)

    简单实例: <audio id="myAudio"></audio> <script> var myAudio = document.getEl ...

  4. springMVC -- 整合UEditor(富文本编辑器)

    工作中需要用到UEditor编辑文本,在与springMVC进行整合时,出现了一些问题,结果导致,在进行图片上传时出现如下提示: 上网查询了很多相关资料,此处简要记录下,防止以后遇到类似问题. 一种方 ...

  5. 修改CMD命令窗口编码并保存方法

    我们经常出现的情况是命令行窗口乱码,默认的cmd窗口显示的中文是GBK编码,要是输出utf-8的就可能会乱码了,那么怎么修改呢. 打开的命令窗口,如果我们要修改成UTF8编码,输入命令: CHCP 6 ...

  6. An App ID with Identifier 'xxxxxx’ is not available. Please ....

    1.完全关闭Xcode; 2.找到钥匙串,将钥匙串(Keychain)中的对应证书移除: 3.再次打开Xcode,通过 Preferences - Account 4. 删除原先的账号重新登录, 搞定 ...

  7. Linux下安装SVN服务(CentOS7下)

    1. 安装 centos(我这里使用的是CentOS7)下yum命令即可方便的完成安装 测试安装是否成功: 2. 建立版本库 创建svn数据目录(subversion默认是把/var/svn作为数据根 ...

  8. C#快速导入海量XML数据至SQL Server数据库

    #region 将Xml中的数据读到Dataset中,然后用SqlBulkCopy类把数据copy到目的表中using (XmlTextReader xmlReader = new XmlTextRe ...

  9. C++ 类的前向声明

    前向声明 在计算机程序设计中, 前向声明是指声明标识符(表示编程的实体,如数据类型.变量.函数)时还没有给出完整的定义.即可以声明一个类而不定义它,只声明类但不知道类的成员变量.函数等具体细节. 如: ...

  10. 使用php实现爬虫程序 套取网站的图片实例

    <?php //去采集a67 图片 网站链接 http://www.xiamov.com/list/1/p.2 你也可以采集其他网站的图片 //创建链接 dedecms--a67 //设置执行不 ...