MVC模式中路由如何生成URL
路由有必要的参数吗
在MVC设计模式中,一个比较重要的步骤是浏览器发送的请求如何生成相应的URL,交给服务器去实例化相应的控制器类然后调用相应的控制器类的对应方法,返回视图给用户。这个流程细说起来比较复杂,这里只记录MVC如何根据用户请求去查询匹配的路由,然后生成相应的URL这一个处理过程。
在定义一个路由的时候,我们只需要在项目文件的App_Start文件夹下的RouteConfig类中操作即可。
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "test",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },//默认值
constraints: new {id=@"/d{3}" },//自定义约束
namespaces: new string[] { });//匹配的路由需要实例化控制器类的命名空间
}
}
在这段断码中,创建了一个名字是“test”的默认路由,里面的参数url为匹配格式,defaults是默认值,constraints是该路由参数的约束, namespaces是匹配到路由后实例化控制器类时候该类的命名空间。指定命名空间可以减少MVC查找控制器类的时间和避免控制器类重名时出现的错误。因为实例化控制器的时候,程序会查找所有实现了IController接口的类,然后找到与用户匹配传入请求对应的控制器类,这个时候如果有两个同名的控制器类,就会出现错误,但是如果制定了命名空间,程序就会到该命名空间下查找控制器类,效率会有微小的提升,实例化该命名空间下的控制器类,避免了重名的情况。如果对MVC有了解,我们就会知道,诸如http://localhost/Home/Index/1 ; http://localhost/Admin/Index/ ;这样的URL将会匹配”test“ 路由。就拿http://localhost/Home/Index/1来说(参数1可能并不是必要的)。因为会匹配test路由,所以对应的控制器类是HomeController,方法是Index,参数是1. 但是他们是如何匹配的呢?接下来会详细记录匹配的过程。
路由的核心是一个非常简单的算法,该算法基于一个由RouteCollection类和一个RouteBase类组成的简单的抽象对象。首先看下路由是如何使用这些类的。尽管可以通过多种方法去生成URL,但是这些方法总是会以调用一个RouteCollection.GetVirtualPath的重载方法而结束。RouteCollection.GetVirtualPath有两个重载的方法。这两个重载方法的签名是:
public VirtualPathData GetVirtualPath(RequestContext requestContext,RouteValueDictionary values)
public VirtualPathData GetVirtualPath(RequestContext requestContext,string name,RouteValueDictionary values);
第一个重载版本第一个参数是接受当前请求的RequesContext,第二个参数是由用户指定的路由值(字典)
在这个过程中,该方法遍历路由字典的每一个路由并且询问”给你这种类型的参数,你能匹配到所有的参数,生成给定参数的URL吗“一旦有一个路由应答能够完成,那么该路由就会返回一个包含了URL的VirtualPathData实例以及其他匹配信息,否则就返回空值,路由表往下移动接着询问。
第二个重载版本,第二个参数是路由的名称,这里如果我们的请求匹配test这个路由,我们直接传入test,程序就会直接去从路由集合中查找test这个路由去匹配,(路由集合的路由不可能重名)。经过一系列逻辑匹配,如果匹配正确就跟第一个重载的方式一样,返回一个包含了URL的VirtaulPathData视力以及包含了其他匹配信息,如果不匹配,程序不会再遍历路由集合,而是直接返回空值。不再匹配其他的路由了。
当我们声明一个超链接的时候,可能会像下面这样声明@Html.ActionLink("测试","Index","Home",new {id=3})。这个方法会反过来调用RouteCollection.GetVirtualPath的方法,并向它传递一个RequestContext对象,一个包含值的字典以及用来生成URL路由名称去匹配超链接 Home/Inde/3这个请求。一旦在路由表中找到匹配这份链接的路由对象,该路由就会返回包含URL以及其他匹配信息的VirtualPathData实例对象,仔细观察test这个路由我们会发现,对于参数id有一个约束,这个约束会自动将字符串转换成正则表达式,如果id是三个整数则匹配,否则不匹配该路由。所以在匹配路由生成URL的时候也会检查约束。这整个过程也许通过一张流程图看起来会更加清晰。

通过这张图片,可能会更加直观的看到,路由是如何生成URL的。总结一下。
1.用户发送诸如(http://localhost/Home/Index/1)这样的请求
2.调用RouteCollection.GetVirtualPath方法得到匹配路由,返回URL以及匹配信息(遍历路由表得到匹配路由)
然后在简单的看一下MVC请求的简单的管道过程
(1)UrlRoutingMoudle尝试使用在RouteTable中注册的路由匹配当前请求(具体匹配过程就是上面的过程)
(2)如果Routale中有一个路由成功匹配,路由模块就会从匹配成功的路路由得到实现了IRouteHandler接口的MVCRouteHandler实例对象;
(3)通过MVCRouteHandler对象的GetHandler()方法得到一个实现了IHttpHandler接口的MVCHandler实例对象。
(4)调用HTTP处理程序的ProcessRequest()方法,并将要处理的请求交给他
(5)通过以上得到了MVCHandler对象,这个对象主要用于实例化控制器类,并调用该实例化控制器类对象上的方法。
MVC模式中路由如何生成URL的更多相关文章
- Thinkphp 修改U方法按路由规则生成url
tp开户路由后,使用U方法是不会按路由规则生成url的,一般我们是要手动修改模版,把里面的U方法去掉,手动修改链接,如果是已经写好的程序,后期才添加路由,修改起链接就太麻烦了 今天无聊就修改了一下U方 ...
- 下面的那一个不属于MVC模式中的对象?
下面的那一个不属于MVC模式中的对象? A. Model B. View C. Collection D. Controller 解答:C MVC是三个单词的缩写,分别为: 模型(Model),视图( ...
- Android入门:MVC模式(中)
MVC 模式的最基本概念是分层设计,把我们的代码基于 View(视图).Model(模型).Controller(控制器)进行分类封装,这样做的目的是为了清晰结构,使代码更易维护和扩展. 在上一篇文章 ...
- 在asp.net mvc模式中使用PartialView返回部分HTML
PartialView(返回HTML(局部)) 在asp.net mvc中返回View时使用的是ViewResult,它继承自ViewResultBase 同时它还有个兄弟PartialViewRes ...
- 在MVC架构中使用CodeSmith生成NHibernate映射对象和实体类
第一步:找到生成模板,如下图 第二步:配置数据库连接(如下图),然后右击第一步找到的模板,点击Excute 第三步:执行操做(如下图) 第四步: 找到之前配置生成的文件夹,找到如下文件(图中标记的文件 ...
- MVC模式中M,V,C每个代表意义,并简述在Struts中MVC的表现方式。
解答: MVC是Model-View-Controller 的缩写,Model代表的是应用的业务逻辑(通过JavaBean,EJB组件实现),View 是应用的表示层(由JSP页面产生)Control ...
- 2016/5/6 thinkphp ①框架 ② 框架项目部署 ③MVC模式 ④控制器访问及路由解析 ⑤开发和生产模式 ⑥控制器和对应方法创建 ⑦视图模板文件创建 ⑧url地址大小写设置 ⑨空操作空控制器 ⑩项目分组
真实项目开发步骤: 多人同时开发项目,协作开发项目.分工合理.效率有提高(代码风格不一样.分工不好) 测试阶段 上线运行 对项目进行维护.修改.升级(单个人维护项目,十分困难,代码风格不一样) 项目稳 ...
- Android中MVP模式与MVC模式比較(含演示样例)
原文链接 http://sparkyuan.me/ 转载请注明出处 MVP 介绍 MVP模式(Model-View-Presenter)是MVC模式的一个衍生. 主要目的是为了解耦,使项目易于维护. ...
- Pro ASP.NET MVC –第三章 MVC模式
在第七章,我们将创建一个更复杂的ASP.NET MVC示例,但在那之前,我们会深入ASP.NET MVC框架的细节:我们希望你能熟悉MVC设计模式,并且考虑为什么这样设计.在本章,我们将讨论下列内容 ...
随机推荐
- 【Hibernate 5】继承映射配置及多态查询
一.继承实现的三种策略 1.1,单表继承.每棵类继承树使用一个表(table per class hierarchy) -->本文主要介绍的继承策略 类继承树对应多个类,要把多个类的信息存放在一 ...
- [drp 8]get和post的区别,以及乱码问题的解决
导读:不管是之前做.NET还是现在做Java的项目,都有涉及到get和post请求,第一次遇到的时候,应该是在人事系统的时候,那时候说要总结,结果一直没有总结.现在,做一个初步的总结,连着总结一下提交 ...
- RAW格式
一.什么是RAW文件?RAW文件主要是一种记录了数码相机传感器的原始信息,同时伴随着一些由相机所产生的一些元数据(metadata,诸如IS0的设置.快门速度.光圈值.白平衡等)的文件.不同的相机制造 ...
- Boost C++: 网络编程1
#include <iostream> #include <boost/asio.hpp> #include <boost/config/compiler/visualc ...
- $watch 和 $apply
1.当你使用 ng-model, ng-repeat 等等来绑定一个元素的值时, AngularJS 为那个值创建了一个 $watch,只要这个值在 AngularJS 的范围内有任何改变,所有的地方 ...
- javascript之for-in循环(for-in Loops)
for-in循环应该用在非数组对象的遍历上,使用for-in进行循环也被称为“枚举”. 从技术上将,你可以使用for-in循环数组(因为JavaScript中数组也是对象),但这是不推荐的.因为如果数 ...
- IIS7 配置URL_REWRITE
webconfig 文件 system.webServer节点下配置rewrite 报错 是因为需要安装URL重写 需要安装: https://www.microsoft.com/zh-cn/down ...
- IIS报错 未将对象引用设置到对象的实例。
在vs中运行正常的项目 ,发布到IIS总是提示 未将对象引用设置到对象的实例. 运行静态页面 html正常,只是打开.aspx页面的时候报错,在确保了数据库,配置,权限均正常的情况下. 错误原因:先安 ...
- Windowsphone本地应用信息与市场信息的获取
本地信息都存放在 WMAppManifest 里面,获取就不用说了...知道位置 就知道怎么获取了.. 主要是讲那个 市场上面的详情怎么获取,就是API调用显示在这个页面里面的详情: public v ...
- Mysql 自定义随机字符串
前几天在开发一个系统,需要用到随机字符串,但是mysql的库函数有没有直接提供,就简单的利用现有的函数东拼西凑出随机字符串来.下面简单的说下实现当时. 1.简单粗暴. select ..., subs ...