浅谈MVC中路由
引言
学习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中路由的更多相关文章
- 浅谈 MVC中的ViewData、ViewBag和TempData
ViewBag和TempData的区别 ViewData ViewBag 它是Key/Value字典集合 它是dynamic类型对像 从Asp.net MVC 1 就有了 ASP.NET MVC3 才 ...
- 浅谈MVC中的service层(转)
概述 mvc框架由model,view,controller组成,执行流程一般是:在controller访问model获取数据,通过view渲染页面. mvc模式是web开发中的基础模式,采用的是分层 ...
- 浅谈HTTP中GET、POST用法以及它们的区别
浅谈HTTP中GET.POST用法以及它们的区别 HTTP定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符.我们可以这样认为: 一 ...
- 浅谈 MVC 和 MTV
浅谈 MVC 和 MTV 一.MVC M:model,模型,就是数据模型,负责数据的存取: V:view,视图,负责页面的展示逻辑: C:controller,控制器,负责业务逻辑的处理: 二.MTV ...
- 浅谈JS中的!=、== 、!==、===的用法和区别 JS中Null与Undefined的区别 读取XML文件 获取路径的方式 C#中Cookie,Session,Application的用法与区别? c#反射 抽象工厂
浅谈JS中的!=.== .!==.===的用法和区别 var num = 1; var str = '1'; var test = 1; test == num //tr ...
- 转:浅谈HTTP中Get、Post、Put与Delete的区别
1.GET请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的select操作一样,只是用来查询一下数据,不会修改.增加数据,不会影响资源的内容,即该请求不会产生副作用.无论进行多少次操 ...
- [转]浅谈电路设计中应用DDR3处理缓存问题
本文转自:浅谈电路设计中应用DDR3处理缓存问题_若海人生的专栏-CSDN博客 DDR系列SDRAM存储芯片的高速率.高集成度和低成本使其理所当然成为存储芯片中的一霸.在PC和消费电子领域自是如此,它 ...
- 浅谈Java中的equals和==(转)
浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...
- 浅谈Linux中的信号处理机制(二)
首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...
随机推荐
- mycat高可用方案
1.建议采用标准的mysql主从复制高可用配置并交付给mycat来完成后端mysql节点的主从自动切换. 2.mycat自身的高可用性 由HAproxy+Mycat集群+Mysql主从所组成的高可用性 ...
- ELF Format 笔记(十)—— 重定位(relocation)
ilocker:关注 Android 安全(新手) QQ: 2597294287 重定位就是把符号引用与符号定义链接起来的过程,这也是 android linker 的主要工作之一. 当程序中调用一个 ...
- 【转】天啦噜!原来Chrome自带的开发者工具还能这么用!(提升JS调试能力的10个技巧)
天啦噜!原来Chrome自带的开发者工具还能这么用! (提升JS调试能力的10个技巧) Chrome自带开发者工具.它的功能十分丰富,包括元素.网络.安全等等.今天我们主要介绍JavaScript ...
- javascript运算符语法概述
× 目录 [1]个数 [2]优先级 [3]结合性[4]类型[5]规则表 前面的话 javascript中的运算符大多由标点符号表示,少数由关键字表示,它们的语法言简意赅,它们的数量却着实不少.运算符始 ...
- SSH-Hibernate+Struts2+Spring的股票项目整合
创建项目之前:我们需要导入我们需要的Hibernate和Struts2和Spring的相关架包.(博客自创,如有问题请留言博主,拒绝盗版,支持正版http://www.cnblogs.com/WuXu ...
- Android 官方推荐 : DialogFragment 创建对话框
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37815413 1. 概述 DialogFragment在android 3.0时 ...
- C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 能支撑10万以上客户端的数据同步下载问题
庞大的业务系统,特别是需要有离线作业操作支持的核心业务系统,需要有强大的基础数据同步功能,基础数据有在增加.有在变动.有在失效,同时有大量的客户端全天侯的在连接服务器.不间断的在处理核心数据. 经过2 ...
- visual studio 2015中的webapi生成helpPage,页面不显示方法说明问题解决
环境: vs2015.win7 参考:http://www.cnblogs.com/Erik_Xu/p/5638381.html 生成的help页面如下:,并没有显示控制器和方法. 原因是:新建项目时 ...
- jQuery美化下拉菜单插件dropkick
dropkick是一款基于jquery库的美化下拉框下拉菜单的插件,它通过定制HTML插入可使丑陋无聊的<select>下拉列表变得美丽. name属性是唯一一个必需的填写的,不过你也应该 ...
- tensorflow学习笔记五:mnist实例--卷积神经网络(CNN)
mnist的卷积神经网络例子和上一篇博文中的神经网络例子大部分是相同的.但是CNN层数要多一些,网络模型需要自己来构建. 程序比较复杂,我就分成几个部分来叙述. 首先,下载并加载数据: import ...