系列目录

请求是如何进入MVC框架的(inbound)

当一个URL请求到来时,系统调用一个注册的IHttpModulesUrlRoutingModule它将完成如下工作

一、在RouteTable.Route中从第一个Route开始查找第一个匹配当前URL的Route。需要同时满足下面的条件,才能算匹配:

1.URL匹配Route属性中Url的模型;

2.所有{}中定义的参数都可以在请求的URL中找到对应,或者参数在Route的Defaults中也有定义,当然Defaults中定义优先级低于URL中的定义,亦或者参数被设置成UrlParameter.Optional

3.参数满足Route的Constraints定义的匹配规则,规则可能是一个正则式,或是一个IRouteConstraint对象。

二、指定匹配的RouteBase将通过GetRouteData方法提供一个RouteData结构,RouteData包含如下四个属性:

1.Route:Route对象自己;

2.RouteHandler:一个实现了IRouteHandler的对象,MVC提供一个MvcRouteHandler类,从MapRoute的源码可以看出,总由MvcRouteHandler担任这个角色。MvcRouteHandler知道如何从RouteData中寻找Controller和Action。事实上MvcRouteHandler会寻找键值为"controller"和"action"参数,所以我们永远需要包含"controller"和"action"两个参数;

3.Values:保存URL中参数的值字典,参数包括{}定义的,Route.Defaults中的,以及从QueryString中获得的;

4.DataTokens:一个附加的字典,主要用于Areas机制,以后会详细讨论。

注:如果GetRouteData返回null的话,就无法进入MVC框架,常见的情况是有直接的静态物理文件能够匹配这个url,通常是一些资源文件,如css,image等文件。可以通过设置RouteCollection的RouteExistingFilestrue,使得用于不匹配静态文件(注意true是不匹配,这个命名和奇怪)。下面的代码是GetRouteData中的代码段,说明了这一机制是如何实现的。

1
2
3
4
5
6
7
8
if (!this.RouteExistingFiles)
{
    string appRelativeCurrentExecutionFilePath = httpContext.Request.AppRelativeCurrentExecutionFilePath;
    if (((appRelativeCurrentExecutionFilePath != "~/") && (this._vpp != null)) && (this._vpp.FileExists(appRelativeCurrentExecutionFilePath) || this._vpp.DirectoryExists(appRelativeCurrentExecutionFilePath)))
    {
        return null;
    }
}

三、调用RouteData中的RouteHandler,同时为RouteHandler提供包括RouteDataHttpContextBase对象等上下文变量,并封装成一个叫requestContext的参数传递给RouteHandler。如果使用MvcRouteHandler,那么至此,就进入了MVC框架

几点注意点:

1.由于上面提到的UrlRoutingModule的搜索行为,Route在RouteCollection中添加的顺序就十分重要了。记住:优先添加形式特殊的Route

2.MvcRouteHandler在调用Controller的Action的时候会自动为Action提供 参数。参数来源于RouteData的键值对,MvcRouteHandler会自动将键名和Action的参数名比较,这种比较是大小写敏感的,所以在 Action中写参数名的时候要注意了,关于这点以后会详细展开;

3.如果希望URL中的参数是可选的,要设置参数为UrlParameter.Optional。

自定义参数匹配规则

Route的Constraints定义URL中参数匹配规则,规则可能是一个正则式,或是一个IRouteConstraint对象。 熟悉的情况是,通过MapRoute的简化API设置Constraints为一个正则式。但如果我们的匹配规则较复杂呢?事实上,我们可以自己实现一个 IRouteConstraint对象,IRouteConstraint只有一个Match方法,所以并不困难。我之前一篇文章ASP.NET MVC的全球化方案中有一个IRouteConstraint的实现。

还有个例子,MVC框架有个HttpMethodConstraint实现了IRouteConstraint,我们可以像下面这样使用:

1
2
3
4
routes.MapRoute(null, "Articles/{id}",
 new { controller = "Articles", action = "Show" },
 new { httpMethod = new HttpMethodConstraint("GET") }
 );

这表示只有以GET方式请求的URL才能匹配这个Route。需要注意的是,我们常常会在Action上加上[HttpGet]或 [HttpPost]来做类似的限定,但两者完全不同,这里的限定是在MVC框架外的,而[HttpGet]是在框架内的,显然这种方法高效些。

劳动果实,转载请注明出处:http://www.cnblogs.com/P_Chou/archive/2010/11/02/details-asp-net-mvc-02.html

深入理解ASP.NET MVC(2)的更多相关文章

  1. 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC

    系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)— ...

  2. [转载]深入理解ASP.NET MVC之ActionResult

    Action全局观 在上一篇最后,我们进行到了Action调用的“门口”: 1 if (!ActionInvoker.InvokeAction(ControllerContext, actionNam ...

  3. 深入理解ASP.NET MVC Day1

    深入理解ASP.NET MVC   ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.NET完全没有关系,是一个全新的Web开发,事实上 ...

  4. 七天学会ASP.NET MVC ——深入理解ASP.NET MVC

    七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC   系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二) ...

  5. 深入理解ASP.NET MVC(6)

    系列目录 Action全局观 在上一篇最后,我们进行到了Action调用的“门口”: 1 if (!ActionInvoker.InvokeAction(ControllerContext, acti ...

  6. 深入理解ASP.NET MVC(5)

    系列目录 回顾 系列的前4节深入剖析了ASP.NET URL路由机制,以及MVC在此基础上是如何实现Areas机制的,同时涉及到inbound和outbound很多细节部分.第2节中提到MvcRout ...

  7. 深入理解ASP.NET MVC(目录)

    学ASP.NET MVC2有一段时间了,也针对性的做了个练习.感觉这个框架还是不错的,所以决定要深入系统的学习一下.看到这样一本书: 作者博客:http://blog.stevensanderson. ...

  8. 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 【转】

    http://www.cnblogs.com/powertoolsteam/p/MVC_one.html 系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会A ...

  9. [转载] ASP.NET MVC (一)——深入理解ASP.NET MVC

    个人认为写得比较透彻得Asp.net mvc 文章,所以转载过来,原文链接在最后: ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.N ...

  10. 理解ASP.NET MVC的路由系统

    引言 路由,正如其名,是决定消息经由何处被传递到何处的过程.也正如网络设备路由器Router一样,ASP.NET MVC框架处理请求URL的方式,同样依赖于一张预定义的路由表.以该路由表为转发依据,请 ...

随机推荐

  1. SQL优化(SQL TUNING)可大幅提升性能的实战技巧之一——让计划沿着索引跑

    我们进行SQL优化时,经常会碰到对大量数据集进行排序,然后从排序后的集合取前部分结果的需求,这种情况下,当我们按照常规思路去写SQL时,系统会先读取过滤获得所有集合,然后进行排序,再从排序结果取出极少 ...

  2. 通过url获取参数信息

    运行结果如下: <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <ti ...

  3. 反向-代理 nginx for Mac 的配置以及使用

       反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端 ...

  4. [转载]彻底卸载oracleXE数据库服务器

    URL:http://www.2cto.com/database/201306/216182.html

  5. 面试题2:单例模式Singleton

    首先,单例模式使类在程序生命周期的任何时刻都只有一个实例, 然后,单例的构造函数是私有的,外部程序如果想要访问这个单例类的话, 必须通过 getInstance()来请求(注意是请求)得到这个单例类的 ...

  6. (C/C++学习笔记) 十. 函数

    十. 函数 ● 基本概念 函数 函数定义 function definition: return_type function_name ( parameter list ) { Body of fun ...

  7. apache ab工具安装测试

    1.安装 安装包下载地址: 将 httpd-2.2.29.tar.gz 解压到目录 /apps/install/httpd-2.2.29 ,这是我放置的位置 cd /apps/install/http ...

  8. mysql-5.6.17-win32安装

    下载免安装压缩文件http://dev.mysql.com/downloads/mysql/ 解压到自定义目录,我这里演示的是D:\wamp\mysql\   复制根目录下的my-default.in ...

  9. node-webkit 入门

    下载node-webkit 点击这里: https://github.com/rogerwang/node-webkit 找到Downloads这一小节,然后下载对应平台的node-webkit预编译 ...

  10. SWIFT模糊效果

    首先创建一个模糊效果 let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Light) 接着创建一个承载模糊效果的视图let blurView ...