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. poj 1821 Fence 单调队列优化dp

    /* poj 1821 n*n*m 暴力*/ #include<iostream> #include<cstdio> #include<cstring> #incl ...

  2. gulp的点点滴滴

    去年用gulp,但一直没有写篇博客,今天有时间无聊写一篇.... 什么是gulp?gulp的官网title上对这个工具有一个比较准确的定义,叫做:基于流的自动化构建工具.如果你查看它的网页源代码,还会 ...

  3. Css3 常见鼠标滑过效果集合

    1.演示地址: http://yaochuxia.github.io/hover/#

  4. Android之使用SharedPreferences保存用户偏好参数

    在Android应用中,我们常需要记录用户设置的一些偏好参数,,此时我们就需要用SharedPreferences和Editor将这些信息保存下来,在下次登录时读取. SharedPreference ...

  5. Android开发手记(29) 基于Http的LaTeX数学公式转换器

    本文将讲解如何通过codecogs.com和Google.com提供的API接口来将LaTeX数学函数表达式转化为图片形式.具体思路如下: (1)通过EditText获取用户输入的LaTeX数学表达式 ...

  6. Struts2 中拦截器和Action的调用关系(写的很好)

    http://blog.csdn.net/hackerain/article/details/6991082

  7. Cookie技术详解

    1. Cookie的特性 属性: 1> name: Cookie的名字 2> value: Cookie的值 3> path: 可选,Cookie的存储路径,默认情况下的存储路径时访 ...

  8. 使用Eclipse搭建C/C++开发环境(转)

    使用Eclipse搭建C/C++开发环境  文章出自:http://www.cnblogs.com/liuxianan/archive/2013/01/15/2861196.html 说明:网上有很多 ...

  9. nginx location

    1. “= ”,字面精确匹配, 如果匹配,则跳出匹配过程.(不再进行正则匹配) 2. “^~ ”,最大前缀匹配,如果匹配,则跳出匹配过程.(不再进行正则匹配) 3. 不带任何前缀:最大前缀匹配,举例如 ...

  10. Java学习----你可以知道对象的工作结果(获取方法的返回值)

    1.写返回类型 2.return 返回值 3.定义变量接受返回值 public class App2 { public String [] print(String msg, int num) { f ...