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; } 
  }
}

  


这是个人的学习程度,如果其中有什么错误的地方请指出来,谢谢! 

posted @ 2012-03-02 16:31  rains  阅读(482)  评论(0编辑  收藏  举报