转载理解ASP.NET MVC系列之三:从URL到Route – Kevin.Yang – 博客园.
这一篇继续从请求说起。
有意义的URL
在经典的Web From请求中,通常我们请求的都是.aspx或者.ashx的文件。
在ASP.NET MVC中,此时的请求不同了。
MVC的请求是一个有意义的URL,虽然不是直接请求的文件,但它还是能够得到网站应用程序处理,还是能得到响应,这是为什么呢?上一节也提过了,那就是Route在中间做了处理。
Route:
在ASP.NET MVC中,从URL到RouteData的映射通过Route对象表示。就是说请求参数在RouteTable中进行匹配,然后返回一个匹配的Route对象RouteData。所以需要先在RouteTable中注册Route信息(这一步在Global.asax.cs中进行), RouteTable的静态属性Routes保存当前应用程序的所有Route信息。
这里需要注意的是,在往RouteTable中添加Route的时候,顺序很重要,因为应用程序在匹配Route的时候,会从上往下依次进行查找,所以特殊的应该放到前边,一般化的放到后边,不然,你的特殊的URL永远被一般化的Route抢先匹配,特殊的Route永远 匹配不到了。
所有的Route都必须派生自RouteBase类。
此类的定义如下:
此类有一个构造函数和两个方法:
GetRouteData方法需要一个HttpContextBase类型的参数,这个参数包含了封装好的有关HTTP请求信息的对象。根据传进来的请求信息 对象进行匹配,如果该路由与当前请求匹配,就会返回一个包含路由定义值的对象,否则返回null;
GetVirtualPath方法需要两个参数,requestContext参数是封装了有关请求的路由的信息的一个对象,values参数包含了路由参数的对象。如果当前路由跟values匹配,它会返回一个包含了生成的URL和有关路由信息的对象。否则返回null。
自定义路由:
在MVC中,我们通常在URL中包含需要使用的控制器名称和控制器中执行的动作,然后还得在后边附加上动作所需的参数。在ASP.NET MVC中提供了一个默认的路由格式供我们使用。
不过如果参数有2个或者更多的时候,如果使用默认的URL格式,这个URL可能是这个样子的:http://www.petshop.com/petshop/search/fish/meno。
www.petshop.com表示网站
petshop表示Controller名
search表示执行的动作。
fish和meno是两个参数,表示要查看fish类别下的meno。
不过这个地址有些太冗长了。
如果我们想直接输入参数,而默认使用petshop控制器和search动作呢?像这个样子:
http://www.petshop.com /fish/meno。
那我们就需要自定义一个路由了:
这个路由通过默认的参数来指定了Controller和Action。
路由约束:
可是上边的Route定义之后,会发现原来有效的Home/Index出现了问题。上边定义的Route只需要两个参数,可是Home/Index也是两个参数,所以,两个参数的请求都被路由到PetShopsRoute上来了。
我们定义PetShopsRoute仅仅是为了处理petshop的类别,Home/Index这个请求我们是不希望被PetShopRoute路由的,所以我们就可以限制Categories参数必须是我们所希望的。
我们可以修改上边的PetShopRoute路由为:
此示例源码下载
自定义路由约束:
要实现自定义路由约束就要实现 IRouteConstraint 接口。此接口的定义为:
此类只包含了一个方法:Match,如果URL参数包含有效值就会返回true,否则返回false。此方法需要5个参数。
httpContext:封装了有关HTTP请求信息的对象;
route:此约束所属的对象。
parameterName:正在检测的参数的名称;
values:一个包含URL的参数的对象:
routeDirection:这个对象只是在处理传入请求或者生成URL时,是否正在执行的约束检查。
关于自定义路由的实例,龙王有一篇文章ASP.NET MVC 之创建自定义路由约束,说得很清晰,推荐大家去看一下。这里我就不再重复了。
好了,这篇就到这里,关于请求的执行过程说完了。
待续。