当前位置:首页 > 从零开始学习ASP.NET MVC:识别URL的Routing组件(二)

从零开始学习ASP.NET MVC:识别URL的Routing组件(二)

点击次数:1598  更新日期:2010-12-31
\n

一.摘要


\n

本篇文章从基础到深入的介绍ASP.NET MVC中的Routing组件. Routing翻译过来是”路由选择”, 负责ASP.NET MVC的第一个工作:识别URL, 将一个Url请求”路由”给Controller. 由于今天下午参加了博客园北京俱乐部的聚会, 所以本篇文章的完工时间晚了点, 还好也是在今天发表, 总算兑现了”每日一篇”的承诺. 不久丁学就会发布北京博客园聚会活动的资料了, 我在这里先预告了!


\n

二.承上启下


\n

第一篇文章中我们已经学会了如何使用ASP.NET MVC, 虽然其中还有很多的细节没有深入了解, 但是对基本的处理流程已经有了认识:来了一个Url请求, 从中找到Controller和Action的值, 将请求传递给Controller处理. Controller获取Model数据对象, 并且将Model传递给View, 最后View负责呈现页面.


\n

而Routing的作用就是负责分析Url, 从Url中识别参数, 如图:


\n

image


\n

这一讲就让我们细致的了解System.Web.Routing及其相关的扩展知识.


\n

三.Routing的作用


\n

第一讲中实例的首页地址是: localhost/home/index


\n

我们发现访问上面的地址, 最后会传递给 HomeController中名为index的action(即HomeController类中的index方法).


\n

当然服务器端不会自己去实现这个功能, 关键点就是在Global.asax.cs文件中的下列代码:

        public static void RegisterRoutes(RouteCollection routes)
\n {
\n routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);

\n

routes.MapRoute(
\n “Default”, // Route name
\n “{controller}/{action}/{id}”, // URL with parameters
\n new { controller = “Home”, action = “Index”, id = “” } // Parameter defaults
\n );

\n

}

\n

protected void Application_Start()
\n {
\n RegisterRoutes(RouteTable.Routes);
\n }

\n

.csharpcode, .csharpcode pre
\n{
\n font-size: small;
\n color: black;
\n font-family: consolas, “Courier New”, courier, monospace;
\n background-color: #ffffff;
\n /*white-space: pre;*/
\n}
\n.csharpcode pre { margin: 0em; }
\n.csharpcode .rem { color: #008000; }
\n.csharpcode .kwrd { color: #0000ff; }
\n.csharpcode .str { color: #006080; }
\n.csharpcode .op { color: #0000c0; }
\n.csharpcode .preproc { color: #cc6633; }
\n.csharpcode .asp { background-color: #ffff00; }
\n.csharpcode .html { color: #800000; }
\n.csharpcode .attr { color: #ff0000; }
\n.csharpcode .alt
\n{
\n background-color: #f4f4f4;
\n width: 100%;
\n margin: 0em;
\n}
\n.csharpcode .lnum { color: #606060; }

\n

回来看我们的Url: localhost/home/index


\n

localhost是域名, 所以首先要去掉域名部分: home/index


\n

对应了上面代码中的这种URL结构: {controller}/{action}/{id}


\n

因为我们建立了这种Url结构的识别规则, 所以能够识别出 Controller是home, action是index, id没有则为默认值”".


\n

这就是Routing的第一个作用:


\n

1.从Url中识别出数据.比如controller,action和各种参数.


\n

如果跟踪程序, 接下来我们会跳转到HomeController中的Index()方法. 这是Routing内部为实现的第二个作用:


\n

2.根据识别出来的数据, 将请求传递给Controller和Action.


\n

但从实例中我们并不知道Routing如何做的这部份工作.第五部分我做了深入讲解.


\n

四.Routing的使用


\n

在分析Routing的实现原理前, 先学习如何使用Routing为ASP.NET MVC程序添加路由规则.


\n

1. 使用MapRoute()方法.


\n

这是最简单的为ASP.NET MVC添加识别规则的方法.此方法有如下重载:

MapRoute( string name, string url);
\nMapRoute( string name, string url, object defaults);
\nMapRoute( string name, string url, string[] namespaces);
\nMapRoute( string name, string url, object defaults, object constraints);
\nMapRoute( string name, string url, object defaults, string[] namespaces);
\nMapRoute( string name, string url, object defaults, object constraints, string[] namespaces);
 

\n

.csharpcode, .csharpcode pre
\n{
\n font-size: small;
\n color: black;
\n font-family: consolas, “Courier New”, courier, monospace;
\n background-color: #ffffff;
\n /*white-space: pre;*/
\n}
\n.csharpcode pre { margin: 0em; }
\n.csharpcode .rem { color: #008000; }
\n.csharpcode .kwrd { color: #0000ff; }
\n.csharpcode .str { color: #006080; }
\n.csharpcode .op { color: #0000c0; }
\n.csharpcode .preproc { color: #cc6633; }
\n.csharpcode .asp { background-color: #ffff00; }
\n.csharpcode .html { color: #800000; }
\n.csharpcode .attr { color: #ff0000; }
\n.csharpcode .alt
\n{
\n background-color: #f4f4f4;
\n width: 100%;
\n margin: 0em;
\n}
\n.csharpcode .lnum { color: #606060; }

\n

name参数:


\n

规则名称, 可以随意起名.当时不可以重名,否则会发生错误:
路由集合中已经存在名为“Default”的路由。路由名必须是唯一的。


\n

url参数:


\n

url获取数据的规则, 这里不是正则表达式, 将要识别的参数括起来即可, 比如: {controller}/{action}


\n

最少只需要传递name和url参数就可以建立一条Routing(路由)规则.比如实例中的规则完全可以改为:

            routes.MapRoute(
\n “Default”,
\n “{controller}/{action}”);

\n

\n

.csharpcode, .csharpcode pre
\n{
\n font-size: small;
\n color: black;
\n font-family: consolas, “Courier New”, courier, monospace;
\n background-color: #ffffff;
\n /*white-space: pre;*/
\n}
\n.csharpcode pre { margin: 0em; }
\n.csharpcode .rem { color: #008000; }
\n.csharpcode .kwrd { color: #0000ff; }
\n.csharpcode .str { color: #006080; }
\n.csharpcode .op { color: #0000c0; }
\n.csharpcode .preproc { color: #cc6633; }
\n.csharpcode .asp { background-color: #ffff00; }
\n.csharpcode .html { color: #800000; }
\n.csharpcode .attr { color: #ff0000; }
\n.csharpcode .alt
\n{
\n background-color: #f4f4f4;
\n width: 100%;
\n margin: 0em;
\n}
\n.csharpcode .lnum { color: #606060; }
\n


\n

defaults参数:


\n

url参数的默认值.如果一个url只有controller: localhost/home/


\n

而且我们只建立了一条url获取数据规则: {controller}/{action}


\n

那么这时就会为action参数设置defaults参数中规定的默认值. defaults参数是Object类型,所以可以传递一个匿名类型来初始化默认值:

new { controller = “Home”, action = “Index” }

\n

.csharpcode, .csharpcode pre
\n{
\n font-size: small;
\n color: black;
\n font-family: consolas, “Courier New”, courier, monospace;
\n background-color: #ffffff;
\n /*white-space: pre;*/
\n}
\n.csharpcode pre { margin: 0em; }
\n.csharpcode .rem { color: #008000; }
\n.csharpcode .kwrd { color: #0000ff; }
\n.csharpcode .str { color: #006080; }
\n.csharpcode .op { color: #0000c0; }
\n.csharpcode .preproc { color: #cc6633; }
\n.csharpcode .asp { background-color: #ffff00; }
\n.csharpcode .html { color: #800000; }
\n.csharpcode .attr { color: #ff0000; }
\n.csharpcode .alt
\n{
\n background-color: #f4f4f4;
\n width: 100%;
\n margin: 0em;
\n}
\n.csharpcode .lnum { color: #606060; }

\n

实例中使用的是三个参数的MapRoute方法:

            routes.MapRoute(
\n “Default”, // Route name
\n “{controller}/{action}/{id}”, // URL with parameters
\n new { controller = “Home”, action = “Index”, id = “” } // Parameter defaults
\n );

\n

\n

.csharpcode, .csharpcode pre
\n{
\n font-size: small;
\n color: black;
\n font-family: consolas, “Courier New”, courier, monospace;
\n background-color: #ffffff;
\n /*white-space: pre;*/
\n}
\n.csharpcode pre { margin: 0em; }
\n.csharpcode .rem { color: #008000; }
\n.csharpcode .kwrd { color: #0000ff; }
\n.csharpcode .str { color: #006080; }
\n.csharpcode .op { color: #0000c0; }
\n.csharpcode .preproc { color: #cc6633; }
\n.csharpcode .asp { background-color: #ffff00; }
\n.csharpcode .html { color: #800000; }
\n.csharpcode .attr { color: #ff0000; }
\n.csharpcode .alt
\n{
\n background-color: #f4f4f4;
\n width: 100%;
\n margin: 0em;
\n}
\n.csharpcode .lnum { color: #606060; }
\n


\n

constraints参数:


\n

用来限定每个参数的规则或Http请求的类型.constraints属性是一个RouteValueDictionary对象,也就是一个字典表, 但是这个字典表的值可以有两种:


\n

  • \n

    用于定义正则表达式的字符串。正则表达式不区分大小写。


    \n

  • \n

    一个用于实现 IRouteConstraint 接口且包含 Match 方法的对象。


    \n

    通过使用正则表达式可以规定参数格式,比如controller参数只能为4位数字:

    new { controller = @”\\d{4}”}
     

    \n

    .csharpcode, .csharpcode pre
    \n{
    \n font-size: small;
    \n color: black;
    \n font-family: consolas, “Courier New”, courier, monospace;
    \n background-color: #ffffff;
    \n /*white-space: pre;*/
    \n}
    \n.csharpcode pre { margin: 0em; }
    \n.csharpcode .rem { color: #008000; }
    \n.csharpcode .kwrd { color: #0000ff; }
    \n.csharpcode .str { color: #006080; }
    \n.csharpcode .op { color: #0000c0; }
    \n.csharpcode .preproc { color: #cc6633; }
    \n.csharpcode .asp { background-color: #ffff00; }
    \n.csharpcode .html { color: #800000; }
    \n.csharpcode .attr { color: #ff0000; }
    \n.csharpcode .alt
    \n{
    \n background-color: #f4f4f4;
    \n width: 100%;
    \n margin: 0em;
    \n}
    \n.csharpcode .lnum { color: #606060; }

    \n

    通过第IRouteConstraint 接口目前可以限制请求的类型.因为System.Web.Routing中提供了HttpMethodConstraint类, 这个类实现了IRouteConstraint 接口. 我们可以通过为RouteValueDictionary字典对象添加键为”httpMethod”, 值为一个HttpMethodConstraint对象来为路由规则添加HTTP 谓词的限制, 比如限制一条路由规则只能处理GET请求:

    httpMethod =  new HttpMethodConstraint(  “GET”, “POST”  )


    \n.csharpcode, .csharpcode pre
    \n{
    \n font-size: small;
    \n color: black;
    \n font-family: consolas, “Courier New”, courier, monospace;
    \n background-color: #ffffff;
    \n /*white-space: pre;*/
    \n}
    \n.csharpcode pre { margin: 0em; }
    \n.csharpcode .rem { color: #008000; }
    \n.csharpcode .kwrd { color: #0000ff; }
    \n.csharpcode .str { color: #006080; }
    \n.csharpcode .op { color: #0000c0; }
    \n.csharpcode .preproc { color: #cc6633; }
    \n.csharpcode .asp { background-color: #ffff00; }
    \n.csharpcode .html { color: #800000; }
    \n.csharpcode .attr { color: #ff0000; }
    \n.csharpcode .alt
    \n{
    \n background-color: #f4f4f4;
    \n width: 100%;
    \n margin: 0em;
    \n}
    \n.csharpcode .lnum { color: #606060; }

    \n

    完整的代码如下:

                routes.MapRoute(
    \n “Default”, // Route name
    \n “{controller}/{action}/{id}”, // URL with parameters
    \n new { controller = “Home”, action = “Index”, id = “” }, // Parameter defaults
    \n new { controller = @”\\d{4}” , httpMethod = new HttpMethodConstraint( “GET”, “POST” ) }
    \n );

    \n

    当然我们也可以在外部先创建一个RouteValueDictionary对象在作为MapRoute的参数传入, 这只是语法问题.

    \n

    .csharpcode, .csharpcode pre
    \n{
    \n font-size: small;
    \n color: black;
    \n font-family: consolas, “Courier New”, courier, monospace;
    \n background-color: #ffffff;
    \n /*white-space: pre;*/
    \n}
    \n.csharpcode pre { margin: 0em; }
    \n.csharpcode .rem { color: #008000; }
    \n.csharpcode .kwrd { color: #0000ff; }
    \n.csharpcode .str { color: #006080; }
    \n.csharpcode .op { color: #0000c0; }
    \n.csharpcode .preproc { color: #cc6633; }
    \n.csharpcode .asp { background-color: #ffff00; }
    \n.csharpcode .html { color: #800000; }
    \n.csharpcode .attr { color: #ff0000; }
    \n.csharpcode .alt
    \n{
    \n background-color: #f4f4f4;
    \n width: 100%;
    \n margin: 0em;
    \n}
    \n.csharpcode .lnum { color: #606060; }
    \n


    \n

    namespaces参数:


    \n

    此参数对应Route.DataTokens属性. 官方的解释是:


    \n

    获取或设置传递到路由处理程序但未用于确定该路由是否匹配 URL 模式的自定义值。


    \n

    我目前不知道如何使用. 请高手指点


    \n

    2.MapRoute方法实例


    \n

    下面通过实例来应用MapRoute方法. 对于一个网站,为了SEO友好,一个网址的URL层次不要超过三层:


    \n

    localhost/{频道}/{具体网页}


    \n

    其中域名第一层, 频道第二层, 那么最后的网页就只剩下最后一层了. 如果使用默认实例中的”{controller}/{action}/{其他参数}”的形式会影响网站的SEO.


    \n

    假设我们的网站结构如下:


    \n

    image


    \n

    下面以酒店频道为例, 是我创建的Routing规则:

            public static void RegisterRoutes(RouteCollection routes)
    \n {
    \n routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);

    \n

    #region 酒店频道部分
    \n // hotels/list-beijing-100,200-3
    \n routes.MapRoute(
    \n “酒店列表页”,
    \n “hotels/{action}-{city}-{price}-{star}”,
    \n new { controller = “Hotel”, action = “list”, city = “beijing”, price=”-1,-1″, star=”-1″ },
    \n new { city=@”[a-zA-Z]*”,price=@”(\\d)+\\,(\\d)+”, star=”[-1-5]“}
    \n );

    \n

    //hotels/所有匹配
    \n routes.MapRoute(
    \n “酒店首页”,
    \n “hotels/{*values}”,
    \n new { controller = “Hotel”, action = “default”, hotelid = “” }
    \n );
    \n #endregion

    \n

    //网站首页.
    \n routes.MapRoute(
    \n “网站首页”,
    \n “{*values}”,
    \n new { controller = “Home”, action = “index”}
    \n );
    \n }

    \n

    .csharpcode, .csharpcode pre
    \n{
    \n font-size: small;
    \n color: black;
    \n font-family: consolas, “Courier New”, courier, monospace;
    \n background-color: #ffffff;
    \n /*white-space: pre;*/
    \n}
    \n.csharpcode pre { margin: 0em; }
    \n.csharpcode .rem { color: #008000; }
    \n.csharpcode .kwrd { color: #0000ff; }
    \n.csharpcode .str { color: #006080; }
    \n.csharpcode .op { color: #0000c0; }
    \n.csharpcode .preproc { color: #cc6633; }
    \n.csharpcode .asp { background-color: #ffff00; }
    \n.csharpcode .html { color: #800000; }
    \n.csharpcode .attr { color: #ff0000; }
    \n.csharpcode .alt
    \n{
    \n background-color: #f4f4f4;
    \n width: 100%;
    \n margin: 0em;
    \n}
    \n.csharpcode .lnum { color: #606060; }
    \n

     

    \n

    实现的功能:


    \n

    (1)访问 localhost/hotels/list-beijing-100,200-3 会访问酒店频道的列表页,并传入查询参数


    \n

    (2)访问 localhost/hotels 下面的任何其他页面地址, 都会跳转到酒店首页.

    \n

    .csharpcode, .csharpcode pre
    \n{
    \n font-size: small;
    \n color: black;
    \n font-family: consolas, “Courier New”, courier, monospace;
    \n background-color: #ffffff;
    \n /*white-space: pre;*/
    \n}
    \n.csharpcode pre { margin: 0em; }
    \n.csharpcode .rem { color: #008000; }
    \n.csharpcode .kwrd { color: #0000ff; }
    \n.csharpcode .str { color: #006080; }
    \n.csharpcode .op { color: #0000c0; }
    \n.csharpcode .preproc { color: #cc6633; }
    \n.csharpcode .asp { background-color: #ffff00; }
    \n.csharpcode .html { color: #800000; }
    \n.csharpcode .attr { color: #ff0000; }
    \n.csharpcode .alt
    \n{
    \n background-color: #f4f4f4;
    \n width: 100%;
    \n margin: 0em;
    \n}
    \n.csharpcode .lnum { color: #606060; }
    \n


    \n

    (3)访问 localhost 下面的任何地址, 如果未匹配上面2条, 则跳转到首页.


    \n

    简单总结:


    \n

    (1)Routing规则有顺序(按照添加是的顺序), 如果一个url匹配了多个Routing规则, 则按照第一个匹配的Routing规则执行.


    \n

    (2)由于上面的规则, 要将具体频道的具体页面放在最上方, 将频道首页 和 网站首页 放在最下方.


    \n

    (3) {*values} 表示后面可以使任意的格式.


    \n

    3.使用Route类


    \n

    MapRoute方法虽然简单, 但是他是本质也是通过创建Route类的实例, 为RouteCollection集合添加成员.


    \n

    下载最新版本的MSDN-Visual Studio 20008 SP1, 已经可以找到Route类的说明.


    \n

    创建一个Route类实例,最关键的是为以下几个属性赋值:


    \n

    \n


    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    属性名称说明举例
    Constraints获取或设置为 URL 参数指定有效值的表达式的词典。 {controller}/{action}/{id}
    DataTokens获取或设置传递到路由处理程序但未用于确定该路由是否匹配 URL 模式的自定义值。 new RouteValueDictionary { { “format”, “short” } }
    Defaults获取或设置要在 URL 不包含所有参数时使用的值。new { controller = “Home”, action = “Index”, id = “” }
    RouteHandler获取或设置处理路由请求的对象。new MvcRouteHandler()
    Url获取或设置路由的 URL 模式。 new { controller = @”[^\\.]*” }

    \n


    这些属性除了RouteHandler以外, 其他的都对应MapRoute方法的参数.RouteHandler是实现了IRouteHandler接口的对象.关于此接口的作用在第五部分Routing深入解析中做讲解.


    \n

    五.Routing深入解析


    \n

    对于一个一般开发人员来说, 上面的知识已经完全足够你使用ASP.NET MVC时使用Routing了.


    \n

    接下来的部分我将深入Routing的机制讲解Routing的高级应用.但是因为是”高级应用”, 加上这篇文章已经太长了, 再加上马上今天就过去了, “每日一篇”的承诺一定要兑现的, 所以不会对所有细节进行讲解. 或者也可以略过此部分.


    \n

    Routing如何将请求传递给Controller?上面讲解Routing作用的时候, 我们就分析出Routing会将请求传递给Controller, 但是Routing如何做的这部份工作我们却看不到.关键在于MapRoute()这个方法封装了具体的细节.


    \n

    虽然MapRoute方法是RouteCollection对象的方法,但是却被放置在System.Web.Mvc程序集中, 如果你的程序只引用了System.Web.Routing, 那么RouteCollection对象是不会有MapRoute方法的. 但是如果你同又引用了System.Web.Mvc, 则在mvc的dll中为RouteCollection对象添加了扩展方法:

           public static void IgnoreRoute(this RouteCollection routes, string url);
    \n public static void IgnoreRoute(this RouteCollection routes, string url, object constraints);
    \n public static Route MapRoute(this RouteCollection routes, string name, string url);
    \n public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults);
    \n public static Route MapRoute(this RouteCollection routes, string name, string url, string[] namespaces);
    \n public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints);
    \n public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces);
    \n public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces);

    \n

    RouteCollection是一个集合,他的每一项应该是一个Route对象. 但是我们使用MapRoute时并没有创建这个对象, 这是因为当我们将MapRoute方法需要的参数传入时, 在方法内部会根据参数创建一个Route对象:

            public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) {
    \n if (routes == null) {
    \n throw new ArgumentNullException(“routes”);
    \n }
    \n if (url == null) {
    \n throw new ArgumentNullException(“url”);
    \n }

    \n

    Route route = new Route(url, new MvcRouteHandler()) {
    \n Defaults = new RouteValueDictionary(defaults),
    \n Constraints = new RouteValueDictionary(constraints)
    \n };

    \n

    if ((namespaces != null) && (namespaces.Length > 0)) {
    \n route.DataTokens = new RouteValueDictionary();
    \n route.DataTokens["Namespaces"] = namespaces;
    \n }

    \n

    routes.Add(name, route);

    \n

    return route;
    \n }


    \n

    上面就是MapRoute方法的实现, 至于在创建Route对象时第二个参数是一个MvcRouteHandler, 它是一个实现了IRouteHandler接口的类. IRouteHandler十分简单只有一个方法:

    IHttpHandler GetHttpHandler(RequestContext requestContext);

    \n

    .csharpcode, .csharpcode pre
    \n{
    \n font-size: small;
    \n color: black;
    \n font-family: consolas, “Courier New”, courier, monospace;
    \n background-color: #ffffff;
    \n /*white-space: pre;*/
    \n}
    \n.csharpcode pre { margin: 0em; }
    \n.csharpcode .rem { color: #008000; }
    \n.csharpcode .kwrd { color: #0000ff; }
    \n.csharpcode .str { color: #006080; }
    \n.csharpcode .op { color: #0000c0; }
    \n.csharpcode .preproc { color: #cc6633; }
    \n.csharpcode .asp { background-color: #ffff00; }
    \n.csharpcode .html { color: #800000; }
    \n.csharpcode .attr { color: #ff0000; }
    \n.csharpcode .alt
    \n{
    \n background-color: #f4f4f4;
    \n width: 100%;
    \n margin: 0em;
    \n}
    \n.csharpcode .lnum { color: #606060; }

    \n

    参数是一个RequestContext 类实例, 这个类的结构也很简单:

        public class RequestContext
    \n {
    \n public RequestContext(HttpContextBase httpContext, RouteData routeData);

    \n

    public HttpContextBase HttpContext { get; }
    \n public RouteData RouteData { get; }
    \n }


    \n

    \n

    .csharpcode, .csharpcode pre
    \n{
    \n font-size: small;
    \n color: black;
    \n font-family: consolas, “Courier New”, courier, monospace;
    \n background-color: #ffffff;
    \n /*white-space: pre;*/
    \n}
    \n.csharpcode pre { margin: 0em; }
    \n.csharpcode .rem { color: #008000; }
    \n.csharpcode .kwrd { color: #0000ff; }
    \n.csharpcode .str { color: #006080; }
    \n.csharpcode .op { color: #0000c0; }
    \n.csharpcode .preproc { color: #cc6633; }
    \n.csharpcode .asp { background-color: #ffff00; }
    \n.csharpcode .html { color: #800000; }
    \n.csharpcode .attr { color: #ff0000; }
    \n.csharpcode .alt
    \n{
    \n background-color: #f4f4f4;
    \n width: 100%;
    \n margin: 0em;
    \n}
    \n.csharpcode .lnum { color: #606060; }
    \n其中的一个属性RouteData就包含了Routing根据Url识别出来各种参数的值, 其中就有Controller和Action的值.


    \n

    归根结底, ASP.NET MVC最后还是使用HttpHandler处理请求. ASP.NET MVC定义了自己的实现了IHttpHandler接口的Handler:MvcHandler, 因为MvcRouteHandler的GetHttpHandler方法最后返回的就是MvcHandler.


    \n

    MvcHandler的构造函数需要传入RequestContext 对象, 也就是传入了所有的所有需要的数据, 所以最后可以找到对应的Controller和Action, 已经各种参数.


    \n

    六.测试Routing


    \n

    因为一个Url会匹配多个routing规则, 最后常常会遇到规则写错或者顺序不对的问题.于是我们希望能够看到Url匹配Routing的结果.


    \n

    其中最简单的办法就是使用RouteDebug辅助类. 这个类需要单独下载dll组件, 我将此组件的下载放在了博客园上:


    \n

    http://files.cnblogs.com/zhangziqiu/RouteDebug-Binary.zip


    \n

    解压缩后是一个DLL文件, 将这个DLL文件添加到项目中并且添加引用.


    \n

    使用方法很简单, 只需要在Application_Start方法中添加一句话:

    RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);

    \n


    比如下面是我的示例中的代码:

            protected void Application_Start()
    \n {
    \n RegisterRoutes(RouteTable.Routes);
    \n RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);
    \n }

    \n

    .csharpcode, .csharpcode pre
    \n{
    \n font-size: small;
    \n color: black;
    \n font-family: consolas, “Courier New”, courier, monospace;
    \n background-color: #ffffff;
    \n /*white-space: pre;*/
    \n}
    \n.csharpcode pre { margin: 0em; }
    \n.csharpcode .rem { color: #008000; }
    \n.csharpcode .kwrd { color: #0000ff; }
    \n.csharpcode .str { color: #006080; }
    \n.csharpcode .op { color: #0000c0; }
    \n.csharpcode .preproc { color: #cc6633; }
    \n.csharpcode .asp { background-color: #ffff00; }
    \n.csharpcode .html { color: #800000; }
    \n.csharpcode .attr { color: #ff0000; }
    \n.csharpcode .alt
    \n{
    \n background-color: #f4f4f4;
    \n width: 100%;
    \n margin: 0em;
    \n}
    \n.csharpcode .lnum { color: #606060; }

    \n


    现在你访问任何URL, 都会出现RouteDebug页面, 如下:


    \n

    image


    \n

    其中不仅有你的所有Routing规则, 还显示了是否匹配.并且按照顺序列出. 还有识别的参数列表.


    \n

    当你不想测试Routing规则的时候则注释掉这一段, 即可回复跳转到View对象上.


    \n

    七.总结


    \n

    本文讲解了ASP.NET MVC中一个关键的组件:Routing的使用. System.Web.Routing在Framework3.5 SP1中已经集成, 也就是说虽然我们还没有ASP.NET MVC的正式版, 但是Routing组件却已经提早发布了. 因为Routing是一个相对独立的组件, 不仅能和ASP.NET MVC配额使用, 也可以用于任何需要URL路由的项目. 另外Routing的作用和Url重写(Url Rewrite)是有区别的, 你会发现Routing和Url Rewrite相比其实很麻烦, 无论是添加规则还是传递参数.对UrlRewite感兴趣的可以去寻找UrlRewrite.dll这个组件, 很简单很强大, 有关两者的异同以及如何使用UrlRewrite这里不在多说了.


    \n

    另外今天博客园北京俱乐部聚会, 听了2位大师的讲座, 见到了至今没记住名字和样子的同行们, 很是激动和兴奋. 期待俱乐部领导将活动照片和资料放出!


    \n

    \n

    .csharpcode, .csharpcode pre
    \n{
    \n font-size: small;
    \n color: black;
    \n font-family: consolas, “Courier New”, courier, monospace;
    \n background-color: #ffffff;
    \n /*white-space: pre;*/
    \n}
    \n.csharpcode pre { margin: 0em; }
    \n.csharpcode .rem { color: #008000; }
    \n.csharpcode .kwrd { color: #0000ff; }
    \n.csharpcode .str { color: #006080; }
    \n.csharpcode .op { color: #0000c0; }
    \n.csharpcode .preproc { color: #cc6633; }
    \n.csharpcode .asp { background-color: #ffff00; }
    \n.csharpcode .html { color: #800000; }
    \n.csharpcode .attr { color: #ff0000; }
    \n.csharpcode .alt
    \n{
    \n background-color: #f4f4f4;
    \n width: 100%;
    \n margin: 0em;
    \n}
    \n.csharpcode .lnum { color: #606060; }
    \n


    \n

    本文的示例下载地址:


    \n

    http://files.cnblogs.com/zhangziqiu/Demo-2.rar

    来源:http://www.cnblogs.com/zhangziqiu

    上一篇:从零开始学习ASP.NET MVC:开天辟地入门篇(一)

  • \n