路由有必要的参数吗

在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的更多相关文章

  1. Thinkphp 修改U方法按路由规则生成url

    tp开户路由后,使用U方法是不会按路由规则生成url的,一般我们是要手动修改模版,把里面的U方法去掉,手动修改链接,如果是已经写好的程序,后期才添加路由,修改起链接就太麻烦了 今天无聊就修改了一下U方 ...

  2. 下面的那一个不属于MVC模式中的对象?

    下面的那一个不属于MVC模式中的对象? A. Model B. View C. Collection D. Controller 解答:C MVC是三个单词的缩写,分别为: 模型(Model),视图( ...

  3. Android入门:MVC模式(中)

    MVC 模式的最基本概念是分层设计,把我们的代码基于 View(视图).Model(模型).Controller(控制器)进行分类封装,这样做的目的是为了清晰结构,使代码更易维护和扩展. 在上一篇文章 ...

  4. 在asp.net mvc模式中使用PartialView返回部分HTML

    PartialView(返回HTML(局部)) 在asp.net mvc中返回View时使用的是ViewResult,它继承自ViewResultBase 同时它还有个兄弟PartialViewRes ...

  5. 在MVC架构中使用CodeSmith生成NHibernate映射对象和实体类

    第一步:找到生成模板,如下图 第二步:配置数据库连接(如下图),然后右击第一步找到的模板,点击Excute 第三步:执行操做(如下图) 第四步: 找到之前配置生成的文件夹,找到如下文件(图中标记的文件 ...

  6. MVC模式中M,V,C每个代表意义,并简述在Struts中MVC的表现方式。

    解答: MVC是Model-View-Controller 的缩写,Model代表的是应用的业务逻辑(通过JavaBean,EJB组件实现),View 是应用的表示层(由JSP页面产生)Control ...

  7. 2016/5/6 thinkphp ①框架 ② 框架项目部署 ③MVC模式 ④控制器访问及路由解析 ⑤开发和生产模式 ⑥控制器和对应方法创建 ⑦视图模板文件创建 ⑧url地址大小写设置 ⑨空操作空控制器 ⑩项目分组

    真实项目开发步骤: 多人同时开发项目,协作开发项目.分工合理.效率有提高(代码风格不一样.分工不好) 测试阶段 上线运行 对项目进行维护.修改.升级(单个人维护项目,十分困难,代码风格不一样) 项目稳 ...

  8. Android中MVP模式与MVC模式比較(含演示样例)

    原文链接 http://sparkyuan.me/ 转载请注明出处 MVP 介绍 MVP模式(Model-View-Presenter)是MVC模式的一个衍生. 主要目的是为了解耦,使项目易于维护. ...

  9. Pro ASP.NET MVC –第三章 MVC模式

    在第七章,我们将创建一个更复杂的ASP.NET MVC示例,但在那之前,我们会深入ASP.NET MVC框架的细节:我们希望你能熟悉MVC设计模式,并且考虑为什么这样设计.在本章,我们将讨论下列内容 ...

随机推荐

  1. 用C++实现网络编程---抓取网络数据包的实现方法

    一般都熟悉sniffer这个工具,它可以捕捉流经本地网卡的所有数据包.抓取网络数据包进行分析有很多用处,如分析网络是否有网络病毒等异常数据,通信协议的分析(数据链路层协议.IP.UDP.TCP.甚至各 ...

  2. leetcode007. Reverse Integer

    /* a good way to predict overflow * each time *10 must predict int overflow * not only the last time ...

  3. 【风马一族_xml】Schema--- xml的约束技术

    Schema 是xml的约束技术,出现的目的是为了替代dtd 本身也是一个xml,非常方便使用xml的解析引擎进行解析 对名称空间有非常好的支持 支持更多的数据类型,并且支持用户自定义数据类型 可以进 ...

  4. 在centos下安装django

    这里有一个不错的Django的学习资料.先收藏一下,以备后用.谢谢 http://www.ziqiangxuetang.com/django/django-install.html 在centos下安 ...

  5. CentOS学习笔记--JDK安装

    JDK安装 大部分的服务都离不开JAVA环境,CentOS里都是OpenJDK,显然我们还是使用JAVA的JDK好.(注:minimal版没有安装OpenJDK,其它版本需要删除这个.) JDK下载 ...

  6. Spring web Flow2学习笔记

    想抽时间研究一下Spring web Flow2,能够找到的唯一电子书是<深入解析Spring+MVC与Web Flow>,我现在摘录本书的一段内容如下,通过这一段,大家可以想象中文背景的 ...

  7. Linux下CPU占用率高分析方法

    一般解决方法是通过top命令找出消耗资源高的线程id,利用strace命令查看该线程所有系统调用1. 通过top命令找到可疑进程PID top - 09:37:18 up 70 days, 16:29 ...

  8. Oracle存储过程知识汇总

    基本语法篇: CREATE OR REPLACE PROCEDURE 存储过程名 //CREATE OR REPLACE PROCEDURE 是一个SQL语句通知Oracle数据库去创建一个叫做ske ...

  9. js如何将纯数字字符串转换为long型

    1.js如何将纯数字字符串转换为long型? js 中 int的存储位数?最大十进制数表示是多少? 精度http://www.jb51.net/article/59808.htm 整数(不使用小数点或 ...

  10. [.ashx檔?泛型处理例程?]基础入门#1....能否用中文教会我?别说火星文?

    原文出處  http://www.dotblogs.com.tw/mis2000lab/archive/2013/08/20/ashx_beginner_01.aspx [.ashx檔?泛型处理例程? ...