blueyund

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

       看了网上不少和URLRewrite相关的技术文章,提供的解决方案不少,下面我结合相关技术文献,通过实例简单的说下个人在程序中应用URLRewrite的方法:

一、.html映射为.aspx

二、2006/6/19映射为default.aspx?log_Year=2006&log_Month=6&log_Day=19

 

实现方法:

应用IIS进行配置(IIS5.0)

       IIS中找到应用程序站点或程序对应的虚拟目录,右击/属性/目录/应用程序配置/配置/应用程序映射选项/,然后选择添加映射,在可执行文件框中浏览aspnet_isapi.dll文件(一般为C:\WINNT\Microsoft.NET\Framework\v1.1.4322\aspnet_isapi.dll),扩展名输入.*(如果针对.html的可直接输入单个扩展即可),动作设为“POST,GET”(为减少不必要的资源耗费,不用设置为全部动作),其他的默认即可。之所以这样做,是要把请求判断权交给ASPNET处理,而不是IIS,所以这个映射是必要的。完成这里的操作后,继续……

       由于用户请求连接时Application_BeginRequest()函数会被触发,所以只需要在这里判断客户端提交的请求就可以了,这就正是上面将IIS筛选权给ASPNET的原因所在。

       方法一、直接判断请求参数信息
 

              string strRawUrl = HttpContext.Current.Request.RawUrl;
              
string strNewUrl;
              
if (Regex.IsMatch(strRawUrl, @"(w+).html", RegexOptions.IgnoreCase))
              
{
                   strNewUrl 
= Regex.Replace(strRawUrl, @"(w+).html"@"$1.aspx", RegexOptions.IgnoreCase);
                   HttpContext.Current.RewritePath( strNewUrl );
              }

              
else if (Regex.IsMatch(strRawUrl, @"(d{4})/(d{1,2})/(d{1,2})(/?)", RegexOptions.IgnoreCase))
              
{
                   strNewUrl 
= Regex.Replace(strRawUrl, @"(d{4})/(d{1,2})/(d{2})(/*)"@"default.aspx?log_Year=$1&log_Month=$2&log_Day=$3",RegexOptions.IgnoreCase);
                   HttpContext.Current.RewritePath( strNewUrl );
//路径显示不变  但执行的是正确的路径
       }


              
//处理图片、样式表路径
       if (Regex.IsMatch(strRawUrl,  @"(d{4})/(d{1,2})/(d{1,2})(/?)([images|styles]+)/(.+)", RegexOptions.IgnoreCase))
              
{
                   strNewUrl 
= Regex.Replace(strRawUrl, @"(d{4})/(d{1,2})/(d{1,2})(/?)([images|styles]+)/(.+)"@"$5/$6",RegexOptions.IgnoreCase);
                   HttpContext.Current.RewritePath( strNewUrl );
              }


              
//验证码页面
       if (Regex.IsMatch(strRawUrl,  @"(d{4})/(d{1,2})/(d{1,2})(/?)checkcode.aspx", RegexOptions.IgnoreCase))
              
{
                   strNewUrl 
= Regex.Replace(strRawUrl, @"(d{4})/(d{1,2})/(d{1,2})(/?)checkcode.aspx"@"checkcode.aspx",RegexOptions.IgnoreCase);
                   HttpContext.Current.RewritePath( strNewUrl );
              }


              
//其他所有页面同样处理
       if (Regex.IsMatch(strRawUrl,  @"(d{4})/(d{1,2})/(d{1,2})(/?)(w+).aspx", RegexOptions.IgnoreCase))
              
{
                   strNewUrl 
= Regex.Replace(strRawUrl, @"(d{4})/(d{1,2})/(d{1,2})(/?)(w+).aspx"@"$5.aspx",RegexOptions.IgnoreCase);
                   HttpContext.Current.RewritePath( strNewUrl );
             }

 

上面的代码很简单,对于正则表达式的应用也比较简单,我就不详述了。同样的方式,通过正则,可改为任何你需要的访问方式,无需DLL支持,

 

方法二、通过配置文件来完成,当然你也可以放到默认的站点配置文件中,这里我是放到单独的config文件里,格式如下:

仍然在在
Application_BeginRequest()中完成。代码如下:

<?xml version="1.0" encoding="utf-8" ?>
<RewriterConfig>
     
<Rules>  
         
<RewriterRule><!--基本的静态页面访问 -->
              
<LookFor>(w+).html</LookFor>
              
<SendTo>$1.aspx</SendTo>
         
</RewriterRule>    
         
<RewriterRule><!--2006/6/19的格式访问-->
              
<LookFor>(d{4})/(d{1,2})/(d{1,2})(/?)</LookFor>
              
<SendTo>default.aspx?log_Year=$1&amp;log_Month=$2&amp;log_Day=$3</SendTo>
         
</RewriterRule>        
         
<RewriterRule><!--重写图片和样式表路径-->
              
<LookFor>(d{4})/(d{1,2})/(d{1,2})(/?)([images|styles]+)/(.+)</LookFor>
              
<SendTo>$5/$6</SendTo>
         
</RewriterRule>                
         
<RewriterRule><!--重写验证码路径-->
              
<LookFor>(d{4})/(d{1,2})/(d{1,2})(/?)checkcode.aspx</LookFor>
              
<SendTo>checkcode.aspx</SendTo>
         
</RewriterRule>        
         
<RewriterRule><!--重写通过2006/6/19格式访问后的 2006/6/19/blogview.aspx?logID=……等-->
              
<LookFor>(d{4})/(d{1,2})/(d{1,2})(/?)(w+).aspx</LookFor>
              
<SendTo>$5.aspx</SendTo>
         
</RewriterRule>             
     
</Rules>
</RewriterConfig>

 

 上面主要完成配置文件的读写和操作,该程序部分来自网上,不过运行时时总是有错误,达不到预期的效果,我修改了部分代码,实现如上,IIS5.0+ASP.NET1.1测试通过。

第二种方法 可直接编辑规则就可以 不用每次都写


 

当然,方法还不止这些,还可以通过自定义错误的页面来完成,方法如下:

<customErrors defaultRedirect="404.aspx" mode="On" />

404页面里进行判断(前提和上面同,需要交给ASPNET处理),当然启用该项,如果上面没有匹配到合适的串,将会交给404.aspx处理。同样global中异常信息也可以提交过来。 

              string strRawUrl = HttpContext.Current.Request.RawUrl;
              
string strNewUrl;
              
if (Regex.IsMatch(strRawUrl, @"(w+).html", RegexOptions.IgnoreCase))
              
{
                   
//避免多重目录访问               strNewUrl=Regex.Replace(Request.RawUrl.ToString(),@"(.*)404(.+)/(w+).html",@"$1$3.aspx",RegexOptions.IgnoreCase);                 //strNewUrl=Regex.Replace(Request.RawUrl.ToString(),@"(.+)[=](.+)(w+).html",@"$2$3.aspx",RegexOptions.IgnoreCase);
                   
//Response.Write(strNewUrl);
                   Response.Redirect(strNewUrl);
              }

              
else if (Regex.IsMatch(strRawUrl, @"(d{4})/(d{1,2})/(d{1,2})(/?)", RegexOptions.IgnoreCase))
              
{
                   strNewUrl 
= Regex.Replace(strRawUrl, @"(.+)[=](.+)(d{4})/(d{1,2})/(d{1,2})(/*)"@"default.aspx?log_Year=$3&log_Month=$4&log_Day=$5");
                   Response.Redirect(strNewUrl);
              }

              
string errMessage="你看到这个页面<br>肯定是什么地方出错了<br>人难免会犯错<br>机器亦然<br>如果你没有搞错地址<br><font color=red>多半是文件不存在或已被删除<br>请确认正确的“连接地址”后再尝试</font>";
              
              
if(Session["Error"]==null)  //接收Global中的应用程序异常信息
                   errMessage+="<br><br><br><font color=red><b>出现错误,已写入事件日志</b></font>";
              
else
errMessage
+="<br><br><br><font color=red><b>"+Session["Error"].ToString()+"</b></font>";     errMessage+="<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>";
              errMessage
+="<div align=center><script language=JavaScript src=http://www1.itsun.com/counter.php?uuid=1553318&style=icon></script></div><br><p align=center><font size=2><b>10秒后转入主页,稍候……</b></font></p>";
              Response.Write(errMessage);

       补充:在Global中捕获程序异常
上面同样的完成处理,不过地址栏显示的地址将不会变动,似乎有一点影响,所以我不打算用这个,不过做为一种思路还是可以考虑的 :),

                   //处理页面异常三种之一
              Exception objErr = Server.GetLastError().GetBaseException();
              
//Exception objErr = Server.GetLastError().Message;
              string err ="Error Caught in Application_Error event " +
                   
"Error in:" + Request.Url.ToString() +
                   
" Error Message:"+ objErr.Message.ToString() +
                   
" Stack Trace:"+ objErr.StackTrace.ToString();
              EventLog.WriteEntry(
"W_Blog",err,EventLogEntryType.Error);  //写入日志
              
//Server.ClearError();       //不清除  留给customerror处理  友好
              HttpContext.Current.Session["Error"]=err;
              Server.Transfer(
"404.aspx"); //404.aspx是所有错误与定向处理的页面
              
//Redirect会导致postback产生而丟失错误信息,所以直接在服务器端执行


 

另外,通过MSDLL来实现,注册、重写规则、……我这里就没不说了,

当然,通过以下方式也可实现:

                     <httpHandlers>

                   <add verb="*" path="*.aspx" type="MyHandler.NewHandler,MyHandler"/>

</httpHandlers>

       将其交给继承IHttpHandler接口的类来处理,大家可参考下MS的附加代码实现。

posted on 2008-08-09 08:44  blueyund  阅读(231)  评论(0编辑  收藏  举报