ASP.NET MVC Framework体验(5):路径选择(URL Routing)

概述

在传统的ASP.NET应用程序中,发生一个请求之后将映射到一个.aspx文件,且会对应到一个具体的物理aspx文件。ASP.NET MVC Framework中,进入一个请求之后,不再是映射到.aspx文件,而是由MVC Framework中提供的路径选择引擎,映射到正确的Controller和Action执行请求。ASP.NET MVC Framework中URL路径映射规则定义在Global.asax中,这在一定程序上带来了很多的灵活性,如果想要修改URL应用结构的话,只需要修改一下映射规则即可,并不需要修改Controller和View中的代码,但是这仍然不够灵活。改变Global.asax代码仍然会导致应用程序的重新编译,本篇文章末尾部分将会介绍如何通过HttpModule定义映射规则在Web.config中。

理解路径选择

先看一下下面这幅图:

TerryLee_MVC_010 

从上图中可以看到,发生一个请求之后,第一步就是路径选择,而映射规则是通过在Routes集合中添加Route实例来注册的,如:

RouteTable.Routes.Add(
            new Route
            {
                Url = "[controller]/[action]",
                Defaults = new { action = "Index"},
                RouteHandler = typeof(MvcRouteHandler)
            });

Route中有四个属性,它的定义如下:

public class Route
{
    public Route();
    public Route(string url, Type routeHandler);
    public Route(string url, object defaults, Type routeHandler);

    public object Defaults { get; set; }
    public Type RouteHandler { get; set; }
    public string Url { get; set; }
    public object Validation { get; set; }
}

其中:

Url指定了请求的Url匹配规则,还定义了URL应该如何分割成(tokenized)不同的参数,URL中可替换的参数,是通过 [参数名称] 的句法来定义的。

Defaults属性定义了一个默认值的字典,可以在进来的URL并不包含某个指定的参数值的情形下使用。

RouteHandler属性定义了在URL被分割成参数,适当的路径选择规则被确定之后,应该用来处理请求的 IRouteHandler 实例。

Validation属性允许我们指定一个路径选择规则匹配需要满足的先决条件,如对参数值使用正则表达式,来过滤一个路径选择规则是否匹配。

II6与II7的区别

在使用ASP.NET MVC Framework时,要注意一点II6和II7的区别,如果在II7下,不需要使用.mvc扩展名,路径选择规则可以如下所示:

RouteTable.Routes.Add(
            new Route
            {
                Url = "[controller]/[action]/[id]",
                Defaults = new { action = "Index", id = (string)null },
                RouteHandler = typeof(MvcRouteHandler)
            });

而在II6下,控制器名后面必须要有.mvc扩展名:

RouteTable.Routes.Add(
            new Route
            {
                Url = "[controller].mvc/[action]/[id]",
                Defaults = new { action = "Index", id = (string)null },
                RouteHandler = typeof(MvcRouteHandler)
            });

路径选择规则的验证

在本文第二节我们提到过Route的一个Validation属性,允许我们指定一个路径选择规则匹配需要满足的先决条件。如下代码段所示,验证Id必须为整数且长度在1到8之间:

RouteTable.Routes.Add(
            new Route
            {
                Url = "Blog.mvc/Detail/[id]",
                Defaults = new { controller = "Blog", action = "Detail" },
                Validation = new { id=@"\d{1,8}" },
                RouteHandler = typeof(MvcRouteHandler)
            });

自定义RouteHandler

在ASP.NET MVC Framework中,提供了很好的扩展功能,如我们可以自定义RouteHandler来实现在Web.config中配置ControllerFactory和ViewFactory。在ASP.NET MVC Framework中,自定义RouteHandler只需要实现IRouteHandler接口并实现GetHttpHandler方法,它的定义如下:

public interface IRouteHandler
{
    IHttpHandler GetHttpHandler(RequestContext requestContext);
}
Fredrik在它的Blog上写了一个完整的示例,有兴趣的朋友可以参考一下。

在Web.config中定义路径选择规则

ASP.NET MVC Framework中路径选择规则定义在Global.asax中的Application_Start方法中,当映射规则发生改变时,如果修改了Application_Start中的代码,必将导致整个应用程序的重新编译,我们完全可以通过HttpModule来实现把映射规则放在配置文件中。如下示例代码所示:
public class RouteBuilder : IHttpModule
{
    public void Init(HttpApplication application)
    {
        RouteConfiguration routeConfig =
            (RouteConfiguration)System.Configuration.ConfigurationManager.GetSection("RouteTable");

        foreach (RouteElement routeElement in routeConfig.Routes)
        {
            Route currentRoute = new Route();

            currentRoute.Defaults = new DefaultsType(routeElement.Defaults);
            currentRoute.Url = routeElement.Url;
            currentRoute.RouteHandler = typeof(MvcRouteHandler);

            RouteTable.Routes.Add(currentRoute);
        }
    }

    public void Dispose()
    {
    }
}
在CodePlex上,已经有了做了这样的开源项目,地址为:http://www.codeplex.com/RouteBuilder,有兴趣的朋友参考一下。

结束语

关于ASP.NET MVC Framework中的路径选择就简单的介绍到这儿了,其实本篇文章后两节都是在推荐一些学习的资料,而关于路径选择的详细内容,在ScottGu的文章里已经写的很仔细了。

最后,再次做个小广告:我在博客园社区中创建了一个Web技术联盟小组,欢迎大家加入。同时,该小组将在近期会有一些活动,来提高社区的氛围:)

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2007-12-16 23:30 TerryLee 阅读(4477) 评论(25)  编辑 收藏 所属分类: ASP.NET

  回复  引用    
#1楼 2007-12-16 23:55 | WaitdDing [未注册用户]
TeeryLee的教学文章更新得好快.我就奇怪了,怎么有这么多的时间来学习这些新的技术呢?
呵呵,最近被一些感情方面的事情困扰着,搞得人精疲力竭,整天无神.真是不能这样下去了.
以后要多多勉励自己了.

加油,TeeryLee 兄,向你看齐了.
  回复  引用  查看    
#2楼 [楼主]2007-12-16 23:57 | TerryLee      
@WaitdDing
感情的事,我真不知道怎么安慰你,但还是希望你能振作起来,还有很多美好的东西等着你呢:)
  回复  引用    
#3楼 2007-12-17 00:05 | Eeyore [未注册用户]
ScrottGu->ScottGu美中不足:)
  回复  引用  查看    
#4楼 [楼主]2007-12-17 00:20 | TerryLee      
@Eeyore
手误:)
  回复  引用    
#5楼 2007-12-17 01:11 | STS [未注册用户]
RouteBuilder.Init明显是错误的做法.

在系统有多个请求同时执行时,
IHttpModule.Init会被多次调用.

  回复  引用  查看    
#6楼 [楼主]2007-12-17 08:42 | TerryLee      
@STS
那放在哪儿比较好呢?
  回复  引用  查看    
#7楼 2007-12-17 09:38 | 没剑      
TeeryLee兄怎么说也是MVP哦~~当然有好多时间的啊·
  回复  引用  查看    
#8楼 2007-12-17 10:48 | Klesh Wong      
"而在II6下,控制器名后面必须要有.mvc扩展名"
why? that's so ugly.
  回复  引用  查看    
#9楼 2007-12-17 13:35 | Ryan Yu      
@Terry Lee
~学习了
  回复  引用  查看    
#10楼 2007-12-17 14:26 | 摩通信息技术      
你好,我公司最近在高薪招聘ASP方面的研发人员,有兴趣的话,可以跟我联系哦,工作地点在苏州市区,联系电话为:0512-88866267,QQ:675574524,EMAIL:kiss_lulu@126.com.
  回复  引用  查看    
#11楼 2007-12-17 14:54 | Trevio      
TeeryLee您好,非常感谢你的这些帮助。但是有很多东西,看下来还是不怎么明白,要是您能做个小程序把这些技术函概了那对我们理解起来就会更容易了。当然我只是随便说说,毕竟您的时间很宝贵!我们也没权利让您去做这样的东西!我也只是希望!
  回复  引用    
#12楼 2007-12-17 16:52 | [心有灵犀] [未注册用户]
迟到啦。。。
  回复  引用    
#13楼 2007-12-17 17:32 | hblqb2 [未注册用户]
你好 我在之前从未接触过设计模式 现在想学习设计模式 但不知从何学起

能否请您能指教和推荐一下关于.NET方向的关于设计模式的书 一位正在努力而务实的学习者
  回复  引用  查看    
#14楼 [楼主]2007-12-17 18:54 | TerryLee      
@没剑
我也是利用晚上时间啊:)
  回复  引用  查看    
#15楼 [楼主]2007-12-17 18:55 | TerryLee      
@Klesh Wong
这个可以理解,毕竟II6出现的比较早
  回复  引用  查看    
#16楼 [楼主]2007-12-17 18:55 | TerryLee      
@Ryan Yu
:)
  回复  引用  查看    
#17楼 [楼主]2007-12-17 18:56 | TerryLee      
@摩通信息技术
发招聘信息可否到招聘区呢?
  回复  引用  查看    
#18楼 [楼主]2007-12-17 18:56 | TerryLee      
@Trevio
最近Web技术联盟小组会有这样的活动
  回复  引用  查看    
#19楼 [楼主]2007-12-17 18:56 | TerryLee      
@[心有灵犀]
:)
  回复  引用  查看    
#20楼 [楼主]2007-12-17 18:56 | TerryLee      
@hblqb2
把你的MSN发Mail给我,我们可以交流一下:)
  回复  引用    
#21楼 2007-12-18 13:33 | zhang08 [未注册用户]
@TerryLee
使用asp.net mvc 有什么好处
  回复  引用  查看    
#22楼 [楼主]2007-12-18 22:10 | TerryLee      
@zhang08
请看我在这里推荐的一篇文章
http://www.cnblogs.com/Terrylee/archive/2007/12/18/1005027.html
  回复  引用    
#23楼 2008-04-17 11:56 | libo [未注册用户]
传统的地址栏参数传递值,在这个MVC里面如何对应!

传递的值如何在Action里面取到
  回复  引用  查看    
#24楼 2008-05-16 01:54 | 镜涛      
学习
  回复  引用  查看    
#25楼 2008-05-16 14:52 | sskset      
你好 TerryLee

我因为项目上的一些原因刚接触ASP.NET MVC FRAMEWORK,我看完了你这5篇文章,我想问一下的是什么情况下会选择使用这个ASP.NET MVC FRAMEWORK ,或者说是,MVC 比较传统的ASP.NET程序有什么优势呢?

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-03-02 10:53 编辑过


相关链接:

历史上的今天:
2005-12-16 华为软件编程规范和范例