路由有必要的参数吗

在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. Android控件大全(三)——RecyclerView

    是时候用RecyclerView来替换ListView和GridView了 好处就不多说了,百度一搜一大把,来介绍下用法 先定义个适配器: public class BottomSheetAdapte ...

  2. php 单例设计模式 example

    <?php class User { //静态变量保存全局变量 private static $_instance=null; //私有化构造函数,防止外界实例化对象 private funct ...

  3. html5文本框提示文字属性为placeholder

    html5文本框提示文字属性为placeholder 例子:  <textarea id="comment" class="commentCont"  n ...

  4. JS跳转到顶部的方法

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>J ...

  5. 用PHP实现守护进程任务后台运行与多线程(php-resque使用说明)

    消息队列处理后台任务带来的问题 项目中经常会有后台运行任务的需求,比如发送邮件时,因为要连接邮件服务器,往往需要5-10秒甚至更长时间,如果能先给用户一个成功的提示信息,然后在后台慢慢处理发送邮件的操 ...

  6. 搭建高性能计算环境(九)、应用软件的安装之gaussian 09

    高斯软件一般使用的都是编译好的二进制版,所以解压缩后设置一下环境变量就可以用了. cd /opt tar xvf g09.tar.gz 设置环境变量,添加到/etc/profile文件中,重新登录后生 ...

  7. UI Button

    iOS开发UI篇—Button基础 一.简单说明 一般情况下,点击某个控件后,会做出相应反应的都是按钮 按钮的功能比较多,既能显示文字,又能显示图片,还能随时调整内部图片和文字的位置 二.按钮的三种状 ...

  8. uglifyjs压缩JS

    一.故事总有其背景 年末将至,很多闲适的时间,于是刷刷微博,接触各种纷杂的信息——美其名曰“学习”.运气不错,遇到了一个新名词,uglifyjs. 据说是用来压缩JS文件的,据说还能优化JS,据说是基 ...

  9. ASP.NET Web API安全认证

    http://www.cnblogs.com/codeon/p/6123863.html http://open.taobao.com/docs/doc.htm?spm=a219a.7629140.0 ...

  10. C# 查询Windows Service 信息 ,所在目录 启动状态

    1.WMI简介WMI是英文Windows Management Instrumentation的简写,它的功能主要是:访问本地主机的一些信息和服务,可以管理远程计算机(当然你必须要拥有足够的权限),比 ...