自定义IHttpModule实现URL重写

HttpModule实现Url重写

 
首先写一个处理URLs重写的类,并且这个类必须继承IHttpHandler接口,
 
在实例化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的事件处理方法。比如这里我们的代码如下:
 
public void Init(HttpApplication context)
{
//context.BeginRequest是开始处理HTTP管线请求时发生的事件
context.BeginRequest += new EventHandler(context_BeginRequest);
//context.Error是当处理过程中发生异常时产生的事件
//context.Error += new EventHandler(context_Error);
}
 
然后在context_BeginRequest这个方法中自己编写处理事件,我们编写的代码如下:
 
void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
string path = context.Request.Path;
string file = System.IO.Path.GetFileName(path);
//重写后的URL地址
Regex regex=new Regex("UserInfo(\\d+).aspx",RegexOptions.Compiled);
Match match=regex.Match(file);
//如果满足URL地址重写的条件
if(match.Success)
{
string userId = match.Groups[1].Value;
string rewritePath = "UserInfo.aspx?UserId=" + userId;
//将其按照UserInfo.aspx?UserId=123这样的形式重写,确保能正常执行
context.RewritePath(rewritePath);
}
}
 
 
 
 
 
上面的代码中采用了正则表达式来进行匹配,使用正则表达式的好处就是在处理格式化文本时相当灵活。除此之外,我们在处理方法中仅仅对满足要求的URL进行重写,对于不满足要求的URL则无需进行重写,所以这样就不会干扰没有重写的URL的正常运行(比如Index.aspx)。
 
仅仅是编写自己的IHttpModule实现还是不够的,我们还需要让处理Web请求的程序直到我们编写的IHttpModule实现的存在,这就需要在web.config中配置。在本实例中只需要在本ASP.NET项目中的web.config节点中增加一个节点(如果已存在此节点则可以不用添加),然后在此节点中增加一个配置即可,对于本实例,这个节点最终内容如下:
 
 
 
 
 
 
 
 
----------------------------------------------------------------
 
 
PS:
 
 
 

///
    ///HttpModule 的摘要说明
    ///
    public class HttpModule : IHttpModule
    {
        public HttpModule()
        {
            //
            //TODO: 在此处添加构造函数逻辑
            //
        }
        ///
        /// 实现接口的Init方法
        ///
        ///    
        public void Init(HttpApplication context)
        {
            //响应请求第一事件
            context.BeginRequest += new EventHandler(ReUrl_BeginRequest);
            //异常事件
            context.Error += new EventHandler(Application_OnError);
        }
      
        ///
        /// 重写Url
        ///
        /// 事件的源
        /// 包含事件数据的 EventArgs
        private void ReUrl_BeginRequest(object sender, EventArgs e)
        {
            //http信息
            HttpContext context = ((HttpApplication)sender).Context;
            //请求路径
            string requestPath = context.Request.Path.ToLower();
           
            //在此处进行URL处理、重写……如:
            string url = requestPath.Replace("要替换的", "新的值");
            //转到处理过的URL,(重写)
            context.RewritePath(url);

        }

        public void Application_OnError(Object sender, EventArgs e)
        {

            HttpApplication application = (HttpApplication)sender;
            HttpContext context = application.Context;
            //清除程序异常
            context.Server.ClearError();
            //异常时可重写向到指定的路径(如401、404页面)
            HttpContext.Current.Response.Redirect("/");
            return;
        }
        ///
        /// 实现接口的Dispose方法
        ///
        public void Dispose()
        {
            //释放资源
        }
    }

 

 

------------------------------------------------------------------------------

 

PS:

 

 

 

首先写一个处理URLs重写的类,并且这个类必须继承IHttpHandler接口,以博客园的程序为例:
public class UrlReWriteModule : System.Web.IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest +=new EventHandler(context_BeginRequest); 
}
public void Dispose()
{
}
}
UrlReWriteModule类就是处理URLs重写的类,继承IHttpHandler接口,实现该接口的两个方法,Init和Dispose。在Init方法里注册自己定义的方法,如上例所示:
content.BeginRequest +=new EventHandler(content_BeginRequest);
BeginRequest是一个事件,在收到新的Http请求时触发,content_BeginRequest就是触发时处理的方法。另外说明一点,HttpModules能注册的方法还有很多,如:EndRequest、Error、Disposed、PreSendRequestContent等等。
在content_BeginRequest方法中具体处理URLs重写的细节,比如,将 http://www.cnblogs.com/rrooyy/archive/2004/10/24/56041.html 重写为 http://www.cnblogs.com/archive.aspx?user=rrooyy&id=56041 (注:我没有仔细看DuDu的程序,这里只是举例而已)。然后将重新生成的Url用HttpContext.RewritePath()方法重写即可,如下:

 

private void context_BeginRequest(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication)sender).Context;
// 获取旧的Url
string url = context.Request.Path.ToLower();
// 重新生成新的Url
string newUrl = ...; // 具体过程略
// 重写Url
context.RewritePath(newUrl);
}
提醒:newUrl的格式不是http://www.infotouch.com/user/archive.aspx,而是从当前应用程序根目录算起的绝对路径,如:user\archive.aspx,这一点请特别注意。
最后要web.config中注册重写URLs的类。


采用标签可以注册一个类;可以移除某个类,如果某个子目录不希望继承父目录的某个Http Module注册,就需要使用这个标签;可以移除所有的Http Module注册。

 

------------------------------------------------------------------------------

PS:项目实例

配置文件如下:

(IIS6)

  <httpModules>
      <add name="urlRewriter" type="XXX.UrlRewriter.HttpModule,XXX.UrlRewriter" />
    </httpModules>

  注意:在IIS7中的节点为moudules

 

   public class HttpModule : IHttpModule
    {
        #region IHttpModule 成员
        public void Dispose()
        {
 
        }
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);
        }
        void context_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;
            HttpContext context = app.Context;
            if (app == null || context == null)
                return;
 
            // URL定向
            Rewriter.URLRewriter(app.Request.Url.AbsoluteUri, app);
        }
        #endregion
    }

 

  public static void URLRewriter(string requestpath, HttpApplication app)
        {
            // 转换成小写
            requestpath = requestpath.ToLower();
 
            if (requestpath.IndexOf("http://") == -1)
            {
                requestpath = "http://" + requestpath;
            }
            List<UrlRules> urlRules = new UrlRules().UrlList("/config/SiteUrlReWriter.config");
            foreach (UrlRules rule in urlRules)
            {
                string lookFor = "^" + rule.LookFor + "$";
                lookFor = lookFor.ToLower();
 
                Regex regex = new Regex(lookFor, RegexOptions.IgnoreCase);
                if (regex.IsMatch(requestpath))
                {
                    string sendTo = regex.Replace(requestpath, rule.SendTo);
 
                    app.Context.RewritePath(ChangUrl(sendTo), true);
                    break;
                }
            }
        }

 

 

 

 

 
 
 

转载于:https://www.cnblogs.com/wangxinming/archive/2013/05/04/3059081.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值