引言

  学习ASP.NET MVC 路由这一关是肯定必不可少的。这一节,我们就来简单介绍下MVC中的路由机制。简单的路由机制相信大家都已了解,这一节主要介绍路由中很少使用的部分。

使用静态URL片段

  在一个路由中,并不是所有的URL片段都要求是动态的,也可以创建具有静态片段的模式。例如以下的路由:

 routes.MapRoute("StaticRoute", "X{controller}/{action}",
new { controller = "Home", action = "Index" },
new string[] { "MyFirstMvcProject.Controllers" });

  我们看到这条路由定义了第一个片段以字母X打头,controller的值是X字母以后的部分,第二个片段Action定义了默认值Index。这条路由将匹配任何X字母开头,controller值是取自第一个片段除字母X以外的部分。

  一个有趣的例子:

  设想下这样的场景,如果您的网站已经发布好久了,用户与网站之间已经形成了某种契约。例如。用户对于这个地址已经非常熟悉http://www.asp.net-example.com/Learn/Index。那么很显然控制器是Learn。如果现在您需要对程序进行重构,那么我们最好保留用户已经熟悉的链接地址。假设重构以后,新的控制器是Home。那么我们可以通过一条保留旧有URL地址的路由来实现这个功能。

 routes.MapRoute("StaticRoute", "Learn/{action}",
new { controller = "Home", action = "Index" },
new string[] { "MyFirstMvcProject.Controllers" });

  上面的路由,我们输入Learn/Index时,路由机制会自动匹配新的控制器Home。这样一方面没有打断网站与已有用户之间形成的契约,同时又对程序功能做了一个较好的迁移。我们在浏览器中运行如下:

  我们看到,我们输入/Learn/Index。路由找到的是HomeController。

定义可变长路由

  我们通过定义可变长度的路由来匹配任意长度的URL。我们通过设置一个*catchall片段变量可以定义对可变片段数量的支持。请看下面的路由

 routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}/{*catchall}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "MyFirstMvcProject.Controllers" }
);

  我们来看下面的例子:

  从这个例子我们看出,我们输入的URL是Home/Index/Id/Do/Operation。我们通过{*catchall}片段变量来获取URL中的片段。我们看到catchall获取的是Do/Operation。说明任意长度的片段变量我们都可以获取到。只是在后续处理时,我们需要自行处理诸如Do/Opeartion这样的片段变量。

按命名空间来区分控制器执行顺序

  从上面一个例子我们看到我们在路由里面设置了namespaces属性的值。如果我们不设置呢?看看会发生上面。请看下面的例子。

  我们看到,我们的项目中存在两个HomeController控制器,浏览器路由机制解析出控制器名称是Home后,两个名称是Home的控制器,MVC框架不知道选择哪一个。这种情况下,我们需要设置下路由器的namespaces属性。这样MVC就会优先从这个命名空间下去寻找控制器。

定义自定义约束

  MVC框架默认给我们提供了根据正则表达式和HTTP方法来约束路由。如果这些方法还是无法满足要求的话,我们可以通过实现IRouteConstraint接口来自定义路由约束。我们首先来看下IRouteConstraint的情况。

         // 摘要:
// 确定 URL 参数是否包含此约束的有效值。
//
// 参数:
// httpContext:
// 一个对象,封装有关 HTTP 请求的信息。
//
// route:
// 此约束所属的对象。
//
// parameterName:
// 正在检查的参数的名称。
//
// values:
// 一个包含 URL 的参数的对象。
//
// routeDirection:
// 一个对象,指示在处理传入请求或生成 URL 时,是否正在执行约束检查。
//
// 返回结果:
// 如果 URL 参数包含有效值,则为 true;否则为 false。
bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection);

  我们看到,这个接口就一个方法Match。MVC路由在匹配路由时会调用这个Match方法看请求的URL与当前路由是否匹配。下面我们还是通过一个例子来看一下把。请看以下例子:

 public class UserAgentConstraint : IRouteConstraint
{
private string requestUserAgent; public UserAgentConstraint(string userAgent)
{
this.requestUserAgent = userAgent;
} public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
bool result = (httpContext.Request.UserAgent != null && httpContext.Request.UserAgent.Contains(this.requestUserAgent));
return result;
}
}

  我们写一条全新的路由来测试下,看看效果。如下:

 routes.MapRoute("chromeRoute", "{controller}/{action}",
new { controller = "Home", action = "Index" },
new { customConstraint = new UserAgentConstraint("Chrome") });

  这条路由使用了我们自定义的约束路由机制,我们看到我们传递了Chrome给自定义的路由匹配器。这样火狐浏览器和IE应该没法进行浏览,谷歌是可以的。打开浏览器试一下。

  我们使用火狐浏览器来访问/Home/Index。会出现404的问题。

  而我们使用谷歌浏览器访问时,是可以正常进行访问的。

对磁盘文件进行路由

  我们知道对于所有的请求并不是都是针对控制器和动作的。也有很多是对静态文件的访问。例如图像,样式文件,JS代码文件等。默认情况下,路由系统在评估应用程序的路由之前,会考察一个URL是否匹配一个磁盘文件。如果匹配,该文件会用来对该请求进行服务。应用程序定义的路由就不会被使用。

  我们可以通过设置routes.RouteExistingFiles = true来对MVC的默认机制进行修改。通过设置为true,意味着对已存在文件也进行路由。为了演示例子,我们还需要配置应用程序服务器,告诉IIS Express以便在请求到达MVC路由系统之前,不要拦截对磁盘文件的请求。请看下面的配置。

 <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />

  找到这一配置节点,将preCondition设置为""即可。

  这时候我们在浏览器中输入Content/CustomerJS.js会看的下面这一幕。

  我们看到,我们启用了对磁盘文件进行路由,这样MVC路由系统会设法找到名称为Content的控制器,这显然不是我们想要的。我们可以通过设置默认值来修复这个问题。

 routes.MapRoute("StaticRoute", "Content/CustomerJS.js",
new { controller = "Home", action = "Index" },
new string[] { "MyFirstMvcProject.Controllers" });

绕过路由系统

  通过使用routes.IgnoreRoute("Content/{filename}.js")我们可以对Content文件夹下的JS文件不进行路由,这样我们上面例子的时候,就会展示JavaScript代码了。

浅谈MVC中路由的更多相关文章

  1. 浅谈 MVC中的ViewData、ViewBag和TempData

    ViewBag和TempData的区别 ViewData ViewBag 它是Key/Value字典集合 它是dynamic类型对像 从Asp.net MVC 1 就有了 ASP.NET MVC3 才 ...

  2. 浅谈MVC中的service层(转)

    概述 mvc框架由model,view,controller组成,执行流程一般是:在controller访问model获取数据,通过view渲染页面. mvc模式是web开发中的基础模式,采用的是分层 ...

  3. 浅谈HTTP中GET、POST用法以及它们的区别

    浅谈HTTP中GET.POST用法以及它们的区别 HTTP定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符.我们可以这样认为: 一 ...

  4. 浅谈 MVC 和 MTV

    浅谈 MVC 和 MTV 一.MVC M:model,模型,就是数据模型,负责数据的存取: V:view,视图,负责页面的展示逻辑: C:controller,控制器,负责业务逻辑的处理: 二.MTV ...

  5. 浅谈JS中的!=、== 、!==、===的用法和区别 JS中Null与Undefined的区别 读取XML文件 获取路径的方式 C#中Cookie,Session,Application的用法与区别? c#反射 抽象工厂

    浅谈JS中的!=.== .!==.===的用法和区别   var num = 1;     var str = '1';     var test = 1;     test == num  //tr ...

  6. 转:浅谈HTTP中Get、Post、Put与Delete的区别

    1.GET请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的select操作一样,只是用来查询一下数据,不会修改.增加数据,不会影响资源的内容,即该请求不会产生副作用.无论进行多少次操 ...

  7. [转]浅谈电路设计中应用DDR3处理缓存问题

    本文转自:浅谈电路设计中应用DDR3处理缓存问题_若海人生的专栏-CSDN博客 DDR系列SDRAM存储芯片的高速率.高集成度和低成本使其理所当然成为存储芯片中的一霸.在PC和消费电子领域自是如此,它 ...

  8. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

  9. 浅谈Linux中的信号处理机制(二)

    首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...

随机推荐

  1. 深入java集合系列文章

    搞懂java的相关集合实现原理,对技术上有很大的提高,网上有一系列文章对java中的集合做了深入的分析, 先转载记录下 深入Java集合学习系列 Java 集合系列目录(Category) HashM ...

  2. ELF Format 笔记(十二)—— 段类型(segment types)

    ilocker:关注 Android 安全(新手) QQ: 2597294287 PT_NULL:如果段类型是 PT_NULL,那相应程序头结构体的其它成员都无意义,该程序头项可被忽略. 暂时还没遇到 ...

  3. MVC MemeberShip vs. Asp.net Identity

    参考 从Membership 到 .NET4.5 之 ASP.NET Identity Extending Identity Accounts and Implementing Role-Based ...

  4. OpenStack 企业私有云的若干需求(3):多租户和租户间隔离(multi-tenancy and isolation)

    本系列会介绍OpenStack 企业私有云的几个需求: 自动扩展(Auto-scaling)支持 多租户和租户隔离 (multi-tenancy and tenancy isolation) 混合云( ...

  5. NOIP模拟赛20161023

    题目名 双色球 魔方 czy的后宫 mex 源文件 ball.cpp/c/pas cube.cpp/c/pas harem.cpp/c/pas mex.cpp/c/pas 输入文件 ball.in c ...

  6. POJ1061青蛙的约会[扩展欧几里得]

    青蛙的约会 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 108911   Accepted: 21866 Descript ...

  7. NYOJ 734

    奇数阶魔方 描述 一个 n 阶方阵的元素是1,2,...,n^2,它的每行,每列和2条对角线上元素的和相等,这样的方阵叫魔方.n为奇数时我们有1种构造方法,叫做“右上方” ,例如下面给出n=3,5,7 ...

  8. WP-Cumulus插件

    链接: 5KB搞定wp-cumulus中文3D Tag问题 WordPress plugin: WP-Cumulus Flash based tag cloud WP-Cumulus支持的3D标签云实 ...

  9. ORA-04091: table is mutating, trigger/function may not see it

    今天在论坛里发现了一个关于ORA-04091的老帖子,收获良多,特此整理一下 关于ORA-04091: table is mutating, trigger/function may not see ...

  10. mysql索引 (校验规则引发的血案)

    EXPLAIN SELECT a.* FROM gc_fin_rate_info  a LEFT JOIN rbac_user b ON a.owner =b.id; 处理之前的情况. 虽然走了索引, ...