ASP.NET MVC 路由(五)

前言

前面的篇幅讲解了MVC中的路由系统,只是大概的一个实现流程,让大家更清晰路由系统在MVC中所做的以及所在的位置,通过模糊的概念描述、思维导图没法让您看到路由的实际运用,特此篇幅来说明一下简单的示例。

路由的命名空间的定义

对于路由当中url规则、默认值、url参数约束这些的定义网上都有,本篇讲一下路由中命名空间的定义。

大家都知道路由的作用,让请求匹配到合理的控制器名称,并且交由控制器工厂来生成控制器来执行请求。然而在项目中难免会命名出相同名称的控制器,我们来模拟一下会发现什么情况。

环境配置

在MVC项目中Controllers文件上右击->添加->控制器,命名为HomeController,并且选择空模板。然后就不用管这个控制器了,什么都不要做了,在此类型所在的命名空间之外添加以下代码:

 namespace AAAAA
 {
     public class HomeController : Controller
     {
         public ActionResult Index()
         {
             this.ViewBag.Name = this.GetType().FullName;
             return View();
         }
     }
 }
 namespace BBBBB
 {
     public class HomeController : Controller
     {
         public ActionResult Index()
         {
             this.ViewBag.Name = this.GetType().FullName;
             return View();
         }
     }
 }

这个时候就是模拟的项目中由于时间的推移引用越来越多的程序集以及各种项目,所可能带来的重复命名,此时Global.asax文件中的默认路由定义:

 routes.MapRoute(
                 "Default", // 路由名称
                 "{controller}/{action}/{id}", // 带有参数的 URL
                 new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值

我们也不用管,直接开始调试,则会看到以下这样的错误,如图:

这种情况给谁都不愿意发生,如果我们此时只需要AAAAA命名空间下的Home控制器怎么办?好办,用路由来配置:

 routes.MapRoute(
                 "",
                 "{controller}/{action}",
                 new { controller = "Home", action = "Index" },
                 null,
                 new string[] { "AAAAA" }
                 );

只需要在MapRoute方法中将所需的命名空间定义为数组传入即可,此时我们右键AAAAA命名空间下的HomeController类型中的Index()方法,点击添加视图->添加,完成后在项目的Views文件夹下的Home文件夹下有个Index.cshtml文件就是添加的视图文件了,打开并且添加如下代码:

 <h2>@ViewBag.Name</h2>

此时我们再执行MVC项目后,如图:

此时有的朋友可能会问,如果想让系统现在AAAAA命名空间下搜寻如果没有则在BBBBB下搜寻控制器,然后让路由这样定义:

 routes.MapRoute(
                 "",
                 "{controller}/{action}",
                 new { controller = "Home", action = "Index" },
                 null,
                 new string[] { "AAAAA","BBBBB" }
                 );

告诉朋友们这样是不行的,如果AAAAA下没有Home控制器还好,如果有系统还是会继续搜寻BBBBB命名空间下的所有类型,关于这里的具体实现将在后面的默认控制器工厂篇幅中讲到。

如果想只在指定的命名空间下搜索的必须是这样定义:

 Route route= routes.MapRoute(
                 "",
                 "{controller}/{action}",
                 new { controller = "Home", action = "Index" },
                 null,
                 new string[] { "AAAAA" }
                 );
 route.DataTokens["UseNamespaceFallback"] = false;

这里的MapRoute()方法会返回一个Route对象,前面我们也说过Route对象的,只不过在注册路由的时候我们完全没有必要获取Route对象的引用,在这里我们需要获取到它,并且要把DataTokens属性集中的UseNamespaceFallback键所对应的值设置为false。这个值将会被传递到控制器工厂中,后续篇幅会讲到。

这样的结果是如果没有搜索到指定的控制器系统也会停止搜索。

ASP.NET MVC 学习