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. 11.2 afternoon

    #include<iostream> #include<cstdio> #define ll long long using namespace std; ll n,ans; ...

  2. Conversion Between DataTable and List in C#

    1.List to DataTable public static DataTable ToDataTable<TSource>(this IList<TSource> dat ...

  3. Java-strurs总结

    这里是自己对自学的struts2 的一个整体 的脉络进行的一个概括,需要学习哪些东西,注重哪些东西: struts2 是主流框架SSH 中的一个"S" ,准备MVC开发标准的一个框 ...

  4. oracle约束条件状态

    Oracle完整性约束有一下4种: • DISABLE NOVALIDATE • ENABLE NOVALIDATE • DISABLE VALIDATE • ENABLE VALIDATE   •  ...

  5. Oracle数据导入导出imp/exp命令总结

    racle数据导入导出imp/exp就相当于oracle数据还原与备份.exp命令可以把数据从远程数据库服务器导出到本地的dmp文件,imp命令可以把dmp文件从本地导入到远处的数据库服务器中. 利用 ...

  6. For Me ...

    一直有做博客的打算,但是这也看不上,那也看不上. 总想着做一个personal blog,界面,风格全由自己设计. 可时间上总是不充裕的. 可技术上总是欠火候的. 可内容上总是待斟酌的. 于是时间被我 ...

  7. 解决Undefined symbols for architecture x86_64: 报错 和 ld: warning: ld: warning: ignoring file警告

    出现这种错误的情况: 用iphone5模拟器编译程序正常, 用iphone5s以上的模拟器编译出现Undefined symbols for architecture x86_64: 报错 和 ld: ...

  8. hdoj 2602(背包)

    Problem D Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Sub ...

  9. 【POJ2185】【KMP + HASH】Milking Grid

    Description Every morning when they are milked, the Farmer John's cows form a rectangular grid that ...

  10. 实用的透明背景mark图标