用自定义IHttpModule实现URL重写.doc_第1页
用自定义IHttpModule实现URL重写.doc_第2页
用自定义IHttpModule实现URL重写.doc_第3页
用自定义IHttpModule实现URL重写.doc_第4页
用自定义IHttpModule实现URL重写.doc_第5页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

在本人拙作ASP.NET夜话第十二章中探讨过ASP.NET底层运行机制的问题,在该书中本人也讲到过了解一些ASP.NET的低层机制对于 我们灵活控制ASP.NET有很大帮助,在该书中本人讲述过如何用自定义的IHttpHandler来实现防盗链功能,由于篇幅限制在该书中没有讲述自定 自定义IHttpModule可以实现什么样的效果,在本篇将讲述利用自定义IHttpModule来实现URL地址重写。 一般来说,要显示一 些动态数据总是采用带参数的方式,比如制作一个UserInfo.aspx的动态页面用于显示系统的UserInfo这个用户信息表的数据,那么需要在其 后带上一个参数来指定要显示的用户信息,比如UserInfo.aspx?UserId=1用于显示表中编号为1的用户的信息,如果为2则显示表中编号为 2的用户信息。在一些系统中我们可能看到的不是这样的效果,可能会看到形如UserInfo2.aspx这样的形式(当然形式可以多样,只要有规律就 行),当点击这样一个链接时看到的效果和UserInfo.aspx?UserId=2的效果一样,这里就用到了URL地址重写的目的。在其它动态语言如 asp、JSP、PHP中要实现URL地址重写需要借助于其它的手段(有一些现成可用的用于实现URL地址重写的dll库),使用这些第三方手段时需要对 IIS做些配置,如果网站放置在购买的虚拟主机上可能就不能够使用了(这种情况我以前就遇见过,当时曾经做过一个J2EE的网站放在虚拟主机上要对 Tomcat做配置才能启用数据库连接池,但是虚拟主机提供商不提供这种服务),其实在ASP.NET中可以通过自定义IHttpModule就可以实现 URL地址重写。 以下文字摘自ASP.NET夜话一书第十二章: “从客户端向IIS发出请求到客户端得到请求的结果这个过程中有一些复杂的操作,涉及到一些非托管的类和非托管的方法,这里就不提了。在托管环境中第一个处理这个请求的类是ISAPIRuntime类。 在 ISAPIRuntime类中的ProcessRequest()方法中实例化HttpWorkerRequest类的实例,接着将 HttpWorkerRequest的实例作为参数交由HttpRuntime类处理,然后在HttpRuntime类中实例化HttpContext类 的实例(这个HttpContext的实例中包含了当前HTTP请求的所有特定HTTP信息,为实现了 IHttpModule 和 IHttpHandler 接口的类提供了对当前 HTTP 请求的 HttpContext 对象的引用,提供对请求的内部 Request、Response 和 Server 属性的访问),再将HttpContext的实例作为参数交由HttpApplicationFactory类(此类是interal的,在外部程序集是 不可见的,MSDN中也找不到此类的说明)用于实例化HttpApplication类的实例,在实例化HttpApplication类的实例的同时还 会根据web.config中的配置(包括系统级和当前网站或虚拟目录级)实例化所有实现IHttpModule接口的集合,这个集合是 HttpModuleCollection类的实例,然后将HttpApplication类的实例作为参数依次调用 HttpModuleCollection中的每一个实现了IHttpModule接口的类的实例的Init()方法。 在这个Init()方法中开始处理一系列HttpApplication类的实例的事件。” 上 面的文字中讲到在实例化HttpApplication类时会根据web.config中的配置(包括系统级和当前网站或虚拟目录级)实例化所有实现 IHttpModule接口的集合,然后会将HttpApplication类的实例作为参数依次调用每个实现了IHttpModule接口的类的实例的 Init()方法,在Init方法中可以添加对请求的特殊处理。在HttpApplication中有很多事件,其中第一个事件就是 BeginRequest事件,在这个事件中我们可以对用户请求的URL进行判断,如果满足某种要求,可以按另外一种方式来进行处理。 比如,当接收到的用户请求的URL是UserInfo(d+).aspx这种形式时(这里采用了正则表达式,表示的是UserInfo(数字).asp这种URL)我们将会运行UserInfo.aspx?UserId=(d+)这样一个URL,这样网页就能正常显示了。 当然实现URL地址重写还需要借助一个类:HttpContext。HttpContext类中定义了RewritePath 方法,这个方法有四种重载形式,分别是: RewritePath(String) 使用给定路径重写 URL。 RewritePath(String, Boolean) 使用给定路径和一个布尔值重写 URL,该布尔值用于指定是否修改服务器资源的虚拟路径。 RewritePath(String, String, String) 使用给定路径、路径信息和一个布尔值重写 URL,该布尔值用于指定是否修改服务器资源的虚拟路径。 RewritePath(String, String, String, Boolean) 使用给定虚拟路径、路径信息、查询字符串信息和一个布尔值重写 URL,该布尔值用于指定是否将客户端文件路径设置为重写路径。 对于这里四个重载方法的区别我不一一详细描述,因为在这里只用带一个参数的重载方法就能满足本文提出的要求。 我们的步骤如下: 首 先编写自定义IHttpModule实现,这个定义只定义了两个方法Dispose()和Init()。在这里我们可以不用关注Dispose()这个方 法,这个方法是用来实现如何最终完成资源的释放的。在Init方法中有一个HttpApplication参数,可以在方法中可以自定义对 HttpApplication的事件处理方法。比如这里我们的代码如下:view plaincopy to clipboardprint?1 public void Init(HttpApplication context) 2 3 /context.BeginRequest是开始处理HTTP管线请求时发生的事件 4 context.BeginRequest += new EventHandler(context_BeginRequest); 5 /context.Error是当处理过程中发生异常时产生的事件 6 /context.Error += new EventHandler(context_Error); 7 然后在context_BeginRequest这个方法中自己编写处理事件,我们编写的代码如下:view plaincopy to clipboardprint?8 void context_BeginRequest(object sender, EventArgs e) 9 10 HttpApplication application = (HttpApplication)sender; 11 HttpContext context = application.Context; 12 HttpResponse response = context.Response; 13 string path = context.Request.Path; 14 string file = System.IO.Path.GetFileName(path); 15 /重写后的URL地址 16 Regex regex=new Regex(UserInfo(d+).aspx,RegexOptions.Compiled); 17 Match match=regex.Match(file); 18 /如果满足URL地址重写的条件 19 if(match.Success) 20 21 string userId = match.Groups1.Value; 22 string rewritePath = UserInfo.aspx?UserId= + userId; 23 /将其按照UserInfo.aspx?UserId=123这样的形式重写,确保能正常执行 24 context.RewritePath(rewritePath); 25 26 注意在上面的代码中采用了正则表达式来进行匹配,使用正则表达式的好处就是在处理格式化文本时相当灵活。除此之 外,我们在处理方法中仅仅对满足要求的URL进行重写,对于不满足要求的URL则无需进行重写,所以这样就不会干扰没有重写的URL的正常运行(比如 Index.aspx)。 从那段从ASP.NET夜话摘出的话中可以看出,仅仅是编写自己的IHttpModule实现还是不够的,我们还 需要让处理Web请求的程序直到我们编写的IHttpModule实现的存在,这就需要在web.config中配置。在本实例中只需要在本 ASP.NET项目中的web.config节点中增加一个节点(如果 已存在此节点则可以不用添加),然后在此节点中增加一个配置即可,对于本实例,这个节点最终内容如下: view plaincopy to clipboardprint?27 28 29 这样我们的URL地址重写就成功了。 下面一个演示显示用户列表的链接的页面设计代码: view plaincopy to clipboardprint?30 31 32 33 34 35 36 无标题页 37 38 39 40 41 42 编号为1的用户信息 43 编号为2的用户信息 44 编号为3的用户信息 45 编号为4的用户信息 46 编号为5的用户信息 47 48 49 50 51 在UserInfo.aspx页面的设计代码如下: view plaincopy to clipboardprint?52 53 54 55 56 57 58 无标题页 59 60 61 62 63 64 65 66 67 68 69 70 UserInfo.aspx页面的对应逻辑代码如下: view plaincopy to clipboardprint?71 using System; 72 using System.Collections; 73 using System.Configuration; 74 using System.Data; 75 using System.Web; 76 using System.Web.Security; 77 using System.Web.UI; 78 using System.Web.UI.HtmlControls; 79 using System.Web.UI.WebControls; 80 using System.Web.UI.WebControls.WebParts; 81 82 public partial class UserInfo : System.Web.UI.Page 83 84 protected void Page_Load(object sender, EventArgs e) 85 86 if (!Page.IsPostBack) 87 88 string queryString = Request.QueryStringUserId; 89 int userId=0; 90 if (int.TryParse(queryString, out userId) 91 92 Literal1.Text = 这是编号为 + userId.ToString() + 的用户的信息。; 93 94 else 95 96 Literal1.Text = 错误的参数; 97 98 99 100 程序的演示效果: 点击进行了URL重写的链接的效果(即UserInfo1.aspx): 点击

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论