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; } } }
这是个人的学习程度,如果其中有什么错误的地方请指出来,谢谢!