UrlRewriteModule类工作流程
初始化
public
void
Init(HttpApplication context)
{
try
{
LoadConfig(HttpRuntime.AppDomainAppPath + "UrlRewriteRule.config");
}
catch (Exception ex)
{
string message = "加载Url Rewriting 配置文件失败。";
Debug.WriteLine(message);
Debug.WriteLine(ex.Message);
throw;
}
context.BeginRequest += new EventHandler(context_BeginRequest);
}
{
try
{
LoadConfig(HttpRuntime.AppDomainAppPath + "UrlRewriteRule.config");
}
catch (Exception ex)
{
string message = "加载Url Rewriting 配置文件失败。";
Debug.WriteLine(message);
Debug.WriteLine(ex.Message);
throw;
}
context.BeginRequest += new EventHandler(context_BeginRequest);
}
读取配置
private
void
LoadConfig(
string
path)
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
if (processors == null)
processors = new List<UrlRewriteProcessor>();
else
processors.Clear();
string lookFor, sendTo;
foreach (XmlNode node in doc.SelectNodes("urlRewriting/rules/rule"))
{
lookFor = node.SelectSingleNode("lookFor/text()").Value;
sendTo = node.SelectSingleNode("sendTo/text()").Value;
if (!String.IsNullOrEmpty(lookFor) && !String.IsNullOrEmpty(sendTo))
processors.Add(new UrlRewriteProcessor(lookFor, sendTo));
}
}
通过XmlDocument直接读取XML内容,实际易用中这里必须要对配置文件进行监视,内容改动以后需要重新加载。
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
if (processors == null)
processors = new List<UrlRewriteProcessor>();
else
processors.Clear();
string lookFor, sendTo;
foreach (XmlNode node in doc.SelectNodes("urlRewriting/rules/rule"))
{
lookFor = node.SelectSingleNode("lookFor/text()").Value;
sendTo = node.SelectSingleNode("sendTo/text()").Value;
if (!String.IsNullOrEmpty(lookFor) && !String.IsNullOrEmpty(sendTo))
processors.Add(new UrlRewriteProcessor(lookFor, sendTo));
}
}
配置文件结构
<?
xml version="1.0" encoding="utf-8"
?>
< urlRewriting >
< rules >
< rule >
< lookFor > /guestbook/(\d+)/delete\.castle </ lookFor >
< sendTo > /guestbook/delete.castle?id=$1 </ sendTo >
</ rule >
< rule >
< lookFor > /guestbook/(\d+)/(\d+)/test.castle </ lookFor >
< sendTo > <![CDATA[ /guestbook/test.castle?year=$1&month=$2 ]]> </ sendTo >
</ rule >
</ rules >
</ urlRewriting >
lookFor为需要重定向的源地址格式正则表达式,sendTo为重定向目标地址。这里配置了删除留言的URL重定向。
< urlRewriting >
< rules >
< rule >
< lookFor > /guestbook/(\d+)/delete\.castle </ lookFor >
< sendTo > /guestbook/delete.castle?id=$1 </ sendTo >
</ rule >
< rule >
< lookFor > /guestbook/(\d+)/(\d+)/test.castle </ lookFor >
< sendTo > <![CDATA[ /guestbook/test.castle?year=$1&month=$2 ]]> </ sendTo >
</ rule >
</ rules >
</ urlRewriting >
例如原来删除ID=2的留言记录URL路径为 http://localhost/guestbook/delete.castle?id=2。现在可以写成 http://localhost/guestbook/2/delete.castle
分析路径进行
private
void
context_BeginRequest(
object
sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
if (processors != null)
{
foreach (UrlRewriteProcessor processor in processors)
{
if (processor.Process(context))
break;
}
}
}
浏览器的请求都会经过context_BeginReqeust方法,在这里分析请求的路径。UrlRewriteProcessor读取配置文件中的正则表达式过滤请求的路径,对满足条件的进行重定向。
{
HttpContext context = HttpContext.Current;
if (processors != null)
{
foreach (UrlRewriteProcessor processor in processors)
{
if (processor.Process(context))
break;
}
}
}
该方法条用非常频繁,所使用的正则表达式预先编译好,存放在UrlRewriteProcessor类中,UrlRewriteProcessor类实例集合为 UrlRewriteModule类的静态成员。
private
static
List
<
UrlRewriteProcessor
>
processors
=
null
;
URL重定向
public
bool
Process(HttpContext context)
{
if (regex.IsMatch(context.Request.FilePath))
{
string newUrl = regex.Replace(context.Request.FilePath, sendTo);
context.RewritePath(newUrl);
return true;
}
else
{
return false;
}
}
使用正则表达式对符合条件的URL进行参数替换以后,调用ASP.NET的HttpContext.RewritePath(string url)方法就完成了URL重定向功能。
{
if (regex.IsMatch(context.Request.FilePath))
{
string newUrl = regex.Replace(context.Request.FilePath, sendTo);
context.RewritePath(newUrl);
return true;
}
else
{
return false;
}
}
web.config中进行配置
要使URL重定向生效,还必须将 UrlRewriteModule配置到系统中才能行。
在web.config中 <system.web/>/<httpModules/>加入以下代码。
<
httpModules
>
< add name ="urlRewriting" type ="Lanjian.GuestBook.UrlRewriteModule, GuestBook" /> <!-- 这儿是为URL重定向而增加的配置 -->
< add name ="monorail" type ="Castle.MonoRail.Framework.EngineContextModule, Castle.MonoRail.Framework" />
</ httpModules >
注意我们的URL重定向HTTPModule在配置文件中,必须放在monorail之前,否则不能生效。
< add name ="urlRewriting" type ="Lanjian.GuestBook.UrlRewriteModule, GuestBook" /> <!-- 这儿是为URL重定向而增加的配置 -->
< add name ="monorail" type ="Castle.MonoRail.Framework.EngineContextModule, Castle.MonoRail.Framework" />
</ httpModules >
今天在 GSpring 发表的《 MonoRail学习笔记三:使用方便功能强大的routing功能》文章中了解到,MonoRail框架中的routing已经实现了该功能。
配置方法可以参考 GSpring的文章。
总结
使用MonoRail框架时,URL重定向可以使用你以前习惯的或者是现有的HTTPModule模块进行处理,或者使用MonoRail的routing。参考源代码,二者实现思路是完全一样的。
同时也要注意,URL重定向配置项必须放在monorail之前。
项目截图:
本文的完整代码可以在 这儿下载。