URLRewriter源码分析
public class RewriterConfigSerializerSectionHandler : IConfigurationSectionHandler
{
#region IConfigurationSectionHandler 成员
XmlSerializer他是可以把xml反序列化成对象,也可以把对象序列化一个xml,但是要求是这两个里面属性都带一直(元素名和默认命名空间)
大概是这个意思,要是还不明白的话,去csdn上查询吧,
http://msdn.microsoft.com/zh-cn/library/system.xml.serialization.xmlserializer(v=VS.80).aspx
public object Create(object parent, object configContext, XmlNode section)
{
声明一个类型为RewriterConfigss序列化对象
XmlSerializer ser = new XmlSerializer(typeof(RewriterConfigss));
讲section(xml)反序列化成RewriterConfigss这个对象
return ser.Deserialize(new XmlNodeReader(section));
}
#endregion
}
另外就是这个类了,web请求流程明白的人们,应该都知道,请求先到httpmodule在到httphandle,然后在返回到httpmodule。
在handle里面就是服务器对用户请求进行处理了,生成页面源码啊,等等,所以,我们要在他到达httphandle之前进行修改url。
重写httpmodule要继承IHttpModule接口,同样要实现里面的init方法了。
public abstract class BaseModuleRewriter:IHttpModule
{
public virtual void Dispose()
{
}
public virtual void Init(HttpApplication context)
{
/ /在请求刚开始的时候
context.BeginRequest += new EventHandler(BaseModuleRewriter_BeginRequest);
}
protected virtual void BaseModuleRewriter_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
Rewrite(app);
}
/// <summary>
/// 地址重写抽象函数
/// </summary>
/// <param name="app"></param>
///
protected abstract void Rewrite(HttpApplication app);
}
下面这个是继承了上面的那个类,所以就不用我说了,当上面的走进那个委托的时候就进子类了这个Rewrite方法了。
我们在web。config中配置的匹配原则有多个RewriterRule
类似:
<RewriterConfig>
<Rules>
<RewriterRule>
<LookFor>~/About-(\d+).html</LookFor>
<SendTo>~\About.aspx?id=$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>~/About-(\d+).html</LookFor>
<SendTo>~\About.aspx?id=$1</SendTo>
</RewriterRule>
</Rules>
</RewriterConfig>
,所以,我们为了方便读取管理,创建了RewriterRuleCollection类
public class ModuleRewriter : BaseModuleRewriter
{
protected override void Rewrite(HttpApplication app)
{
//获取规则集合
RewriterRuleCollection rules = RewriterConfigss.GetConfig().Rules;
for (int i = 0; i < rules.Count; i++)
{
string lookFor = rules[i].LookFor;
Regex reg = new Regex(lookFor, RegexOptions.IgnoreCase);
if (reg.IsMatch("~"+app.Request.RawUrl))
{
//获取目的URL
string sendToUrl = reg.Replace("~"+ app.Request.RawUrl, rules[i].SendTo);
//地址重写 (发送到httphandle进行处理)
app.Context.RewritePath(sendToUrl);
break;
}
}
}
}
在Rewriter源码中这个类叫做RewriterConfiguration,我感觉改成这个更容易让人理解,从节点中你就看,你就明白了。
但是在源码中你可以看到类中加了一个[XmlRoot("RewriterConfig")] 属性,这个意思就是把这个名字加到这个类的xml根部,在这里就是说的
ConfigurationManager.GetSection("RewriterConfigss")),他返回的值是
<Rules>
<RewriterRule>
<LookFor>~/About-(\d+).html</LookFor>
<SendTo>~\About.aspx?id=$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>~/About-(\d+).html</LookFor>
<SendTo>~\About.aspx?id=$1</SendTo>
</RewriterRule>
</Rules>
你看看缺少什么,对,缺少我们的根,(RewriterConfiguration)HttpContext.Current.Cache["RewriterConfig"],这句话,就是为什么这个
源码中的这个类RewriterConfiguration可以的原因了。
[Serializable()]
public class RewriterConfigss
{
表示RewriterConfigss的属性
public RewriterRuleCollection Rules { get; set; }
/// <summary>
/// 该方法从web.config中读取规则集合,并使用了Cache以避免频繁IO操作
/// </summary>
/// <returns></returns>
public static RewriterConfigss GetConfig()
{
//使用缓存
if (HttpContext.Current.Cache["RewriterConfig"] == null)
HttpContext.Current.Cache.Insert("RewriterConfig", ConfigurationManager.GetSection("RewriterConfigss"));
return (RewriterConfigss)HttpContext.Current.Cache["RewriterConfig"];
}
}
[Serializable()]
public class RewriterRuleCollection : CollectionBase
{
/// <summary>
/// 向集合中添加新规则
/// </summary>
/// <param name="r">RewriterRule对象</param>
public virtual void Add(RewriterRule r)
{
this.InnerList.Add(r);
}
/// <summary>
/// 获取或设置项
/// </summary>
public RewriterRule this[int index]
{
get { return (RewriterRule)this.InnerList[index];}
set { this.InnerList[index] = value; }
}
}
这是个人的学习程度,如果其中有什么错误的地方请指出来,谢谢!

浙公网安备 33010602011771号