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. android MediaCodec 音频编解码的实现——转码

    原文地址:http://blog.csdn.net/tinsanmr/article/details/51049179 从今天开始 每周不定期更新博客,把这一周在工作与学习中遇到的问题做个总结.俗话说 ...

  2. enter 默认搜索

    onkeydown=" if(event.keyCode==13) Search(); "

  3. discuz论坛几种安全策略(一)

    安全问题 最近公司准备搭建一个discuz论坛,大头让我调研一下discuz的安全策略,并提出如下几点要求: 1.防止php上传漏洞2.防止大量刷新攻击限制某个IP大量刷新某一页面导致论坛宕机3.防止 ...

  4. sql 作业+游标 自动备份数据库

    前言 昨天有个同事在客户的服务器上面弄数据库,不小心执行了一条 sql 语句 TRUNCATE TABLE xxx 碉堡了吧,数据全没了  - - ,然后就是在网上拼命的搜索关于数据恢复的软件,搞了一 ...

  5. PIL安装记录,编译支持jpeg png

    PIL是python理想的图片处理module,但是想要良好的支持各种图片,还需要检查一下几步,否则会提示:IOError: decoder jpeg not available之类的. 我的环境:L ...

  6. IOS应用程序生命周期&启动周期函数

    —程序的生命周期         a.程序的生命周期是指应用程序启动到应用程序结束整个阶段的全过程         b.每一个IOS应用程序都包含一个UIApplication对象,IOS系统通过该U ...

  7. Sprite Kit教程:初学者

    作者:Ray Wenderlich 原文出处:点击打开链接 http://www.raywenderlich.com/42699/spritekit-tutorial-for-beginners 转自 ...

  8. 在模型中获取网络数据,刷新tableView

    model .h #import <Foundation/Foundation.h> #import "AFHTTPRequestOperationManager.h" ...

  9. C# Dll动态链接库

    新建一个类库. 2     编写一个简单的类库实例,例如:DllTest在默认名为:calss1.cs里编写代码一下是一个简单的:在控制台显示 “你以成功调用了动态连接!”sing System;us ...

  10. 浮点数精确表示,java陷阱

    /** 浮点数表示问题 @author husky */ public class Change { public static void main(String[] args) { double n ...