您的位置:首页 > 其它

URLRewrite重写的简单应用和自定义出错页面

2006-05-25 18:02 381 查看
URLRewrite重写的简单应用和自定义出错页面
看了网上不少和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&log_Month=$2&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测试通过。




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


try




...{


string path = Server.MapPath("~/Rewrite.config");


XPathDocument myXPathDocument = new XPathDocument(path);


XPathNavigator myXPathNavigator = myXPathDocument.CreateNavigator();


XPathNodeIterator myXPathNodeIterator = myXPathNavigator.Select("//RewriterRule");


while (myXPathNodeIterator.MoveNext())




...{


XPathNavigator nav2 = myXPathNodeIterator.Current.Clone();


string oldString = "", newString = "";


XPathNodeIterator it2 = nav2.Select("LookFor");


while (it2.MoveNext())




...{


oldString = it2.Current.Value;


break;


}


it2 = nav2.Select("SendTo");


while (it2.MoveNext())




...{


newString = it2.Current.Value;


break;


}




if (oldString != "" && newString != "")




...{


string strRawUrl = HttpContext.Current.Request.RawUrl;


string strNewUrl;


if (Regex.IsMatch(strRawUrl, oldString, RegexOptions.IgnoreCase))




...{


strNewUrl = Regex.Replace(strRawUrl, oldString, newString, RegexOptions.IgnoreCase);


HttpContext.Current.RewritePath(strNewUrl);


//return;


}


}


}


}


catch (Exception ex)




...{


HttpContext.Current.Response.Write(ex.Message);


}


#endregion


当然,方法还不止这些,还可以通过自定义错误的页面来完成,方法如下:
<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产生而丟失错误信息,所以直接在服务器端执行




另外,通过MS的DLL来实现,注册、重写规则、……我这里就没不说了,
当然,通过以下方式也可实现:
<httpHandlers>
<add verb="*" path="*.aspx" type="MyHandler.NewHandler,MyHandler"/>
</httpHandlers>
将其交给继承IHttpHandler接口的类来处理,大家可参考下MS的附加代码实现。

《完》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐