System.Web.Routing入门及进阶 上篇

System.Web.Routing已经作为一个程序集包含在.net3.5sp1中发布了。虽然我们并没有在3.5sp1中发现Asp.net Mvc的踪迹,但是亦以感觉到它离我们不远了。

System.Web.Routing用于在Asp.netWeb应用程序中进行URLRouting

 

所谓UrlRouting就是将一个地址映射为另一个地址,比如我访问/chsword/2008/08/27.html其实是访问了/chsword/article.aspx?y=2008&m=08&d=27这个地址,URLRouting使我们的URL看起来非常漂亮。

 

本文将分2部分介绍UrlRouting的使用分别为入门篇与进阶篇。

文章的前提:

1.         安装Visual Studio 2008 sp1或其它IDE的等同版本。

2.         建立一个Asp.net Web ApplicationAsp.net Web应用程序)

3.         引用System.Web.Routing程序集。

UrlRouting的实现原理

如果你不是追求理论的人,仅仅是务实主义,可以直接从准备工作读起。

为了方便大家理解我绘制了一个UML图,其中通过RouteTableRoutes这个属性可以获取一个RouteCollectionSingleton模式,虽然在其中并没有判断值不存在时才初始化的Singleton的标志性行为,但是它是在Application_Start事件中进行初始化的,并且直到应用程序进程终结,所以是Singleton模式的。

 

而通过以下方式将Route添加到RouteTable.Routes

RouteTable.Routes.Add(new Route());

以上代码仅为表示其流程,这个代码是不能正确执行的,因为Route没有提供无参构造函数。

Route初始化时则是利用RouteValueDictionary来加入默认值及规则到Route

另外Route还有一个IRouteHandler的实现对象,IRouteHandler的实现对象提供了一个GetHttpHandler方法来获取用于处理URLIHttpHandler

 

这么说还是停留在抽象层次的,下面我们以一些简单例子来带你驭起UrlRouting

准备工作

由于须要一个处理UrlIHttpHandler所以我们先定义一个实现了IHttpHandler接口的类。

就叫它MyPage,由于我们要与IRouteHandler交互,所以除了实现IHttpHandler的方法之外还要声明一个RequestContext类型的属性

public class MyPage:IHttpHandler {
        
public RequestContext RequestContext { getprivate set; }
        
public MyPage(RequestContext context)
        {
            
this.RequestContext = context;
        }
        
#region IHttpHandler 成员
        
public virtual void ProcessRequest(HttpContext context){}
        
public bool IsReusable {
            
get { return false; }
        }
        
#endregion
    }

这样我们就拥有了一个自己的IHttpHandler

下面我们实现一个IRouteHandler

    public class MyRouteHandler : IRouteHandler {
        
#region IRouteHandler 成员
        
public IHttpHandler GetHttpHandler(RequestContext requestContext) {
            
return new MyPage(requestContext);
        }
        
#endregion
    }

这里实现了IRouteHandlerGetHttpHandler方法,使之返回刚才我们实现的MyPage

这样我们前期的2个工作就做完了,我们可以来实现UrlRouting了。

实现第一个UrlRouting

其实UrlRouting在定义完上两个规则后就很简单了。

Golbal.asax(没有可以新建一个)的Application_Start事件中写如下代码

 

protected void Application_Start(object sender, EventArgs e) {
            RegisterRoutes(RouteTable.Routes);
        }
        
public static void RegisterRoutes(RouteCollection routes) {
            routes.Add(
new Route("{page}.aspx",new MyRouteHandler()));
        }

这样我们就定义了第一个UrlRouting规则就是对xxxx.aspx这类的Url进行Routing

 

但是我们仅仅是定义了处理了什么样的Url,却没定义如何处理。

我们应该在刚刚定义的MyPageProcessRequest方法中定义如何处理。

我们将ProcessRequest方法实现如下:

 

public virtual void ProcessRequest(HttpContext context){
context.Server.Execute(        RequestContext.RouteData.Values[
"page"].ToString().Replace("_","/")+".aspx"
            );
}

很显然这里的RequestContext.RouteData.Values["page"]就是取到刚才的规则{page}.aspx中的page的值即,如果我访问index.aspxRequestContext.RouteData.Values["page"]就是index

我这里的定义是将”_”替换为”/”所以就是将list_index.aspx这样的URL转到list/index.aspx这样的网页上。

我们建立一些测试用的网页如下图所示:

 

 

在这些网页里随意写些可以分辨网页的文字。

则访问list_chsword.aspx时自动Routing到了list/chsword.aspx上了

总结一下UrlRouting与以下有关:

1.         Application_Start中定义的规则

2.         自己实现的IHttpHandler

 

这样您对于UrlRouting就算是入门了,下一篇我们将来讲一些进阶设置。

 

预计内容:

  • 规则的默认值
  • 正则规则设置
  • 使用技巧

 

 System.Web.Routing入门及进阶 下篇

 

 

posted @ 2008-08-27 11:47 重典 阅读(15644) 评论(22)  编辑 收藏 网摘 所属分类: ASP.NET MVC

  回复  引用  查看    
#1楼2008-08-27 11:51 | Gray Zhang      
正好博问里有人问怎么用routing定位到web service,因为web service本身不是IHttpHandler,楼主有什么方法吗
  回复  引用  查看    
#2楼[楼主]2008-08-27 12:07 | 重典      
@Gray Zhang
我感觉并不在于IHttpHandler吧

可以将自己定义的IHttpHandler的ProcessRequest实现为
public virtual void ProcessRequest(HttpContext context)
{

WebService1 w=new WebService1();
context.Response.Write(w.HelloWorld());
context.Response.End();
}

类似这样

当然我这里简单写了,可以自己实现用Reflection来通过UrlRouting的不同调用不同的方法

当然可以序列化为SOAP或JSON输出。

  回复  引用  查看    
#3楼2008-08-27 12:25 | Gray Zhang      
主要是,web service可以选择性地序列化为xml或者json,而这里的w.HelloWorld()很可能返回的是一个对象,如何序列化对象的任务不应该交由自己实现的IHttpHandler嘛,不然不就是把web service的proxy重新做了一遍……
  回复  引用  查看    
#4楼[楼主]2008-08-27 12:30 | 重典      
@Gray Zhang
嗯,是的,我再试试其它方法

  回复  引用  查看    
#5楼2008-08-27 12:37 | 陛下      
了解,看上去比早前是有进步了。支持!
  回复  引用  查看    
#6楼[楼主]2008-08-27 12:42 | 重典      
@陛下
多谢^^

  回复  引用  查看    
#7楼2008-08-27 13:56 | 隐姓埋名      
藏之~
  回复  引用  查看    
#8楼[楼主]2008-08-27 14:06 | 重典      
@隐姓埋名
^^

  回复  引用  查看    
#9楼2008-08-27 16:27 | 巫云      
好多框架都用这样的URL重写了。
  回复  引用  查看    
#10楼[楼主]2008-08-27 16:29 | 重典      
@巫云
这个算是最官方的版本了

  回复  引用  查看    
#11楼2008-11-13 09:08 | 逸之羊      
学习了!
  回复  引用  查看    
#12楼2008-12-26 16:35 | 玉开      
ZHEYANG做UrlRewrite就方便了。
  回复  引用  查看    
#13楼2009-01-13 10:19 | 房子小轩      
学了半天,
web.config中没有注册这个,怎么也搞不定!
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

  回复  引用  查看    
#14楼[楼主]2009-01-13 10:56 | 重典      
@房子小轩
不好意思,因为前提于ASP.NET MVC的所以没有说明

  回复  引用  查看    
#15楼2009-01-13 14:18 | 房子小轩      
@重典
  我贴出来只是为了让其他跟我一样的菜鸟,注意一下~
  没有其他的意思~
  :)

  回复  引用  查看    
#16楼[楼主]2009-01-13 14:50 | 重典      
@房子小轩
呵呵,知道知道,我也仅是补充一下文中不足,呵呵
兄弟是刚刚来园子吗?

  回复  引用  查看    
#17楼2009-03-10 15:52 | stg609      
那Urlrewriter和asp.net routing有什么区别吗?听说routing的话只能访问到web控件,而urlrewriter则可以访问任何控件,比如HTML控件。是这样吗?
  回复  引用  查看    
#18楼[楼主]2009-03-10 18:42 | 重典      
@stg609
其实区别挺大的,
首先就是实现原理不一样,一个于IHttpHandler一个早于它
使用URLWrite时URL只能硬编码
比如首页index.html,你都要写死了

但UrlRouting却可能动态生成,更改规则时自动也生成相应的连接

  回复  引用  查看    
#19楼2009-04-10 15:48 | Dreaming      
重典同志,首先非常感谢你给我们提供的视频~致敬~~
另外有个问题请教一下,正式版的MVC像以下定义router不行吗?
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
routes.MapRoute(
"Member",
"Member/{action}.htm",
new { controller = "Member", action = "Login" }
);
这是我在老赵的视频上看到的,他这样写看上去很方便,不用写IRouteHandler了,但我这像他这样写去匹配不到,反正只匹配第一条规则。请问用这样的写法吗??疑惑ing

  回复  引用  查看    
#20楼[楼主]2009-04-10 16:38 | 重典      
@Dreaming
MapRoute是可以用的,而且一直可以,但它是ASP.NET MVC中写的对Route的一个扩展方法,本身不属于Routing

而我写这篇 文章是针对Routing的 和ASP.NET MVC也基本没什么关系,为做到通用性,所以没有在文中使用任何依赖于其它框架的方法

  回复  引用    
#21楼2009-06-15 16:16 | 疑问[未注册用户]
RequestContext 这个类是在哪个命名空间下,一直没有找着
  回复  引用  查看    
#22楼[楼主]2009-06-15 16:18 | 重典      
@疑问
是属性,不是类

发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1277451





相关文章:

相关链接: