技巧百问(10):UrlRewrite以及二级UrlRewrite

        这个系列已经很久没写了,因为太懒了。今天想起还是写一些东西,虽然这个用了很久了,但是也可以再看看。
        之前在 转贴中说到了UrlRewrite这一技术,这个技术的实质就是通过获取当前Url地址匹配对应的规则,传递给真实的访问页面。而这一技术带来的是相对的安全以及访问的便利。从我个人的理解来看,就是让人可以通过简单的方便的方式来访问,对一部分人来说是不让其知道具体的真实页面。
         从转贴中了解到,要实现这个功能要么自定义HTTP模块类,要么通过ISAPI来实现,相对来说前者更具有通用性以及扩展性。
         要实现自定义HTTP模块类则要实现接口IHttpModule,它其中有Init方法,同时要实现Init中参数HttpApplication的 AuthenticateRequest事件,以及我们定义的Rewrite的抽象方法。
public   virtual   void  Init(HttpApplication app)
        {
            app.AuthorizeRequest 
+=   new  EventHandler( this .BaseModuleRewriter_AuthorizeRequest);
        }

        
public   virtual   void  Dispose() { }


        
protected   virtual   void  BaseModuleRewriter_AuthorizeRequest( object  sender, EventArgs e)
        {
            HttpApplication app 
=  (HttpApplication)sender;
            
/// 一般重写
             Rewrite(app.Request.Path, app);
            
/// 二级域名重写
             // Rewrite(app.Request.Url.AbsoluteUri, app);
        } 

        
protected   abstract   void  Rewrite( string  requestedPath, HttpApplication app);
         其中注释掉的部分为二级域名重写的方法,唯一的区别就是获取的地址为绝对地址,因为一般重写即是: www.abc.com/123/实际访问为 www.abc.com/index.aspx?id=123,而二级域名重写则是:123.abc.com实际访问为 www.abc.com/index.aspx?id=123。这两个虽然结果是一样的,但是他们的实现方法是不同的。要实现二级域名重写首先就是要域名支持泛解析,所谓泛解析就是不论是123.abc.com、abc.com、abc123.abc.com都访问的是 www.abc.com,这个也是二级域名实现的基础。因为在传递真实的地址的时候就是通过泛解析来让地址进入 www.abc.com再加上后面的index.aspx?id=123。
         上面定义了重写的抽象方法,现在我就要来实现这个重写方法,流程则是读取xml或者Config中对应的正则来匹配获取的Url地址,然后传递到真实的地址,所以我就还要实现几个方法,第一个是读取Config或Xml中对应的正则以及真实地址的方法,第二个是对读取出来的数据分离出正则和真实地址,第三个为了方便在重写的时候快速的对其匹配对第二个分离的数据进行集合。
  1  // 以下代码为读取数据,并加入到集合中
  2  public   class  RewriterConfigSerializerSectionHandler : IConfigurationSectionHandler
  3      {
  4           public   object  Create( object  parent,  object  configContext, System.Xml.XmlNode section)
  5          {
  6              XmlSerializer ser  =   new  XmlSerializer( typeof (RewriterConfiguration));
  7 
  8               return  ser.Deserialize( new  XmlNodeReader(section));
  9          }
 10 
 11  [Serializable()]
 12      [XmlRoot( " RewriterConfig " )]//这里可以随便定义,主要通过这个名字的节点来获取正则匹配。cxbkkk
 13       public   class  RewriterConfiguration
 14      {
 15          
 16           private  RewriterRuleCollection rules;   
 17           public   static  RewriterConfiguration GetConfig()
 18          {
 19               if  (HttpContext.Current.Cache[ " RewriterConfig " ==   null )
 20                  HttpContext.Current.Cache.Insert( " RewriterConfig " , ConfigurationSettings.GetConfig( " RewriterConfig " ));
 21 
 22               return  (RewriterConfiguration)HttpContext.Current.Cache[ " RewriterConfig " ];
 23          }
 24 
 25           #region  Public Properties
 26           ///   <summary>  
 27           ///   正则匹配集合
 28           ///   </summary>  
 29           public  RewriterRuleCollection Rules
 30          {
 31               get
 32              {
 33                   return  rules;
 34              }
 35               set
 36              {
 37                  rules  =  value;
 38              }
 39          }
 40           #endregion
 41      } 
 42 
 43  public   class  RewriterRule
 44      {
 45           private   string  lookFor, sendTo;
 46 
 47           public   string  LookFor
 48          {
 49               get
 50              {
 51                   return  lookFor;
 52              }
 53               set
 54              {
 55                  lookFor  =  value;
 56              }
 57          }
 58 
 59 
 60           public   string  SendTo
 61          {
 62               get
 63              {
 64                   return  sendTo;
 65              }
 66               set
 67              {
 68                  sendTo  =  value;
 69              }
 70          }
 71 
 72      } 
 73 
 74  [Serializable()]
 75       public   class  RewriterRuleCollection : CollectionBase
 76      {
 77           ///   <summary>  
 78           ///  加入一个新匹配到集合. 
 79           ///   </summary>  
 80      
 81           public   virtual   void  Add(RewriterRule r)
 82          {
 83               this .InnerList.Add(r);
 84          }
 85 
 86           ///   <summary>  
 87           ///  集合的索引. 
 88           ///   </summary>  
 89           public  RewriterRule  this [ int  index]
 90          {
 91               get
 92              {
 93                   return  (RewriterRule) this .InnerList[index];
 94              }
 95               set
 96              {
 97                   this .InnerList[index]  =  value;
 98              }
 99          }
100      } 
101 
102      } 
          上面的我统一命名空间为Rewrite.config,我们还要实现匹配后传递地址的过程。
           按照取Url-->匹配正则-->传递地址,这样的过程实现。
 1  protected   override   void  Rewrite( string  requestedPath, System.Web.HttpApplication app)
 2          {
 3              RewriterRuleCollection rules  =  RewriterConfiguration.GetConfig().Rules;
 4 
 5               for  ( int  i  =   0 ; i  <  rules.Count; i ++ )
 6              {
 7                   /// 一般重写
 8                   string  lookFor  =   " ^ "   +  RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].LookFor)  +   " $ " ;
 9                   /// 二级域名重写
10                   // string lookFor = "^" + rules[i].LookFor + "$"; 
11 
12                  Regex re  =   new  Regex(lookFor, RegexOptions.IgnoreCase);
13 
14                   if  (re.IsMatch(requestedPath))
15                  {
16                       string  sendToUrl  =  RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo));
17 
18                      app.Context.Trace.Write( " ModuleRewriter " " Rewriting URL to  "   +  sendToUrl);
19 
20                      RewriterUtils.RewriteUrl(app.Context, sendToUrl);
21                       break ;                 }
22              }
23 
24              app.Context.Trace.Write( " ModuleRewriter " " Exiting ModuleRewriter " );
25          }
         在匹配的时候就涉及到了使用什么样的地址来匹配,二级域名因为使用的绝对地址,所以这里就不需要通过我们定义的方法Resolve来补充相对地址。现在剩下的就是RewriteUtils中的地址补充以及地址传递。
 1    internal   static   void  RewriteUrl(HttpContext context,  string  sendToUrl)
 2          {
 3               string  x, y;
 4              RewriteUrl(context, sendToUrl,  out  x,  out  y);
 5          }
 6 
 7           internal   static   void  RewriteUrl(HttpContext context,  string  sendToUrl,  out   string  sendToUrlLessQString,  out   string  filePath)
 8          {
 9 
10               if  (context.Request.QueryString.Count  >   0 )
11              {
12                   if  (sendToUrl.IndexOf( ' ? ' !=   - 1 )
13                      sendToUrl  +=   " & "   +  context.Request.QueryString.ToString();
14                   else
15                      sendToUrl  +=   " ? "   +  context.Request.QueryString.ToString();
16              }
17 
18               string  queryString  =  String.Empty;
19              sendToUrlLessQString  =  sendToUrl;
20               if  (sendToUrl.IndexOf( ' ? ' >   0 )
21              {
22                  sendToUrlLessQString  =  sendToUrl.Substring( 0 , sendToUrl.IndexOf( ' ? ' ));
23                  queryString  =  sendToUrl.Substring(sendToUrl.IndexOf( ' ? ' +   1 );
24              }
25 
26              filePath  =   string .Empty;
27              filePath  =  context.Server.MapPath(sendToUrlLessQString);
28 
29              context.RewritePath(sendToUrlLessQString, String.Empty, queryString); 
30          }
31 
32           internal   static   string  ResolveUrl( string  appPath,  string  url)
33          {
34               if  (url.Length  ==   0   ||  url[ 0 !=   ' ~ ' )
35                   return  url; 
36               else
37              {
38                   if  (url.Length  ==   1 )
39                       return  appPath; 
40                   if  (url[ 1 ==   ' / '   ||  url[ 1 ==   ' \\ ' )
41                  { 
42                       if  (appPath.Length  >   1 )
43                           return  appPath  +   " / "   +  url.Substring( 2 );
44                       else
45                           return   " / "   +  url.Substring( 2 );
46                  }
47                   else
48                  {
49                       if  (appPath.Length  >   1 )
50                           return  appPath  +   " / "   +  url.Substring( 1 );
51                       else
52                           return  appPath  +  url.Substring( 1 );
53                  }
54              }
55          }
            然后就是对配置文件或Xml中添加访问模块的名称,以及以读取中定义的名称为节点的正则匹配和传递地址。
<configSections>
    <section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter.Config" />
  </configSections>
<httpModules>
      <add type="URLRewriter.ModuleRewriter, URLRewriter" name="ModuleRewriter" />
    </httpModules>
            正则匹配为
<RewriterConfig>
    <Rules>
      <!--一般重写正则-->
      <RewriterRule>
        <LookFor>~/(\d+)\.aspx</LookFor>
        <SendTo>~/Default.aspx?theid=$1</SendTo>
      </RewriterRule>
      <!--二级重写正则-->
      <!--<RewriterRule>
        <LookFor>http://(\d+)\.abc.com/</LookFor>
        <SendTo>/Default.aspx?theid=$1</SendTo>
      </RewriterRule>-->
    </Rules>
  </RewriterConfig>


               到这里重写就完成了,而其他重写都是在这些基础之上,应该可以通过组合之类的实现多种重写。以上的东西希望可以让你清晰的了解UrlRewrite的流程和原理。



参考:
         MSDN

转载于:https://www.cnblogs.com/cxbkkk/archive/2006/11/27/574434.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值