系列目录

请求是如何进入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. vEthernet(默认交换机) 无法访问网络

    VMware 开启虚拟机 最近公司由无线网转为有线时,我用VMware Workstation Pro装的几个系统,其中一个 ubuntu无法访问网页,在ubuntu运行ifconfig -a ,直接 ...

  2. 华为root手机

  3. POJ 2109 巧妙解法

    Int最大是10^9.所以一般思路是二分+高精度.但是double 范围是10^(-307)-10^308所以可以用double型.k^n=p.所以有k=p^(1/n). 见代码: #include& ...

  4. linux thtree level page tables

    To translate a virtual address into a physical one, the CPU must take the contents of each level fie ...

  5. 用redis做简单的任务队列(一)

    队列本身其实是个有序的列表,而Redis是支持list的,我们可以查看Redis的官方文档 http://redis.io/commands#list,其中我们可以对这个队列的两端分别进行操作,所以其 ...

  6. 配置total commander 显示所有或特定文件夹 (带点的文件夹)

    在配置|忽略列表 下可以添加或删除需要隐藏的文件夹通配符.

  7. SharePoint Word Service-PowerShell

    1. 配置转换进程 Set-SPWordConversionServiceApplication –Identity "Word Automation Services" –Act ...

  8. (转)git合并多个commit

    原文地址:http://platinhom.github.io/2016/01/02/git-combine_commit/ 有时commit多了看着会不爽.所以想合并掉一些commit. 这里是最简 ...

  9. jQuery一句话实现全选

    一句话实现全选 function selectAll(checkbox){ $('input[type=checkbox]').prop('checked', $(checkbox).prop('ch ...

  10. php property_exists

    property_exists("Device",$prop))判断Device 类中是否存在 $prop 这个属性该函数用来判断一个类中是否存在某个属性. 这里分析了php面向对 ...