现在的位置: 首页 > 综合 > 正文

UrlRewriter.NET 与 UrlRewrittingNet.UrlRewriter

2013年02月10日 ⁄ 综合 ⁄ 共 2159字 ⁄ 字号 评论关闭

UrlRewriter.NETUrlRewritingNet.UrlRewrite是ASP.NET中做URL重写比较常用的两个组件。两者实现方式大致都差不多,都是通过HTTP Module来处理。以这种方式处理,都会遇到一个问题,就是ASP.NET的Form控件总是以重写后的URL为Postback的地址。比如:http://detail11.aspx重写到http://detail.aspx?id=11;当postback到当前页后,地址栏里就是http://detail.aspx?id=11,而不是前者的友好地址。在解决这个问题上,两者处理方式不同,也导致了一些问题的出现。

UrlRewriter.NET重写了ASP.NET内置的Form控件,可以在页面里直接用这个控件替换掉ASP.NET Form控件,对于ASP.NET 2.0,推荐采用Control Adapter的形式,在App_Browsers目录下新建Form.browser文件,填充下面的内容:
<browsers>

    <browser refID="Default">
        <controlAdapters>
            <adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
      adapterType="Intelligencia.UrlRewriter.FormRewriterControlAdapter,
Intelligencia.UrlRewriter" />
        </controlAdapters>
    </browser>

</browsers>

UrlRewritingNet.UrlRewrite的处理方式没有这么繁琐,它没有额外的配置,也不需要替换内置的Form,那它是如何解决这个问题的呢?查看源码大致可以看出,它在重写了URL到目标page handler之后,在page初始化之前,又将URL重写回了原始的friendly URL,它是通过处理Page.PreInit事件来处理的。所以整个过程发生了两次重写,先是在页面生命周期早期的BeginRequest阶段,把原始URL重写到目标URL,在目标URL对应的Page Handler开始执行后,并且在所有控件初始化之前(Page.PreInit事件正好在这个阶段)在把URL重写回去,这样包括Form控件在内的其他控件就是使用原始的URL了,postback时就不会发生之前所说的问题了。

但是这种方式又导致了另一个问题,ASP.NET 2.0支持跨页的Postback(cross-page postback)。但当使用了UrlRewritingNet.UrlRewrite后,访问PreviousPage时会报错,具体看这里PostBackUrl PreviousPage problem,而且这个Bug到目前还没有解决方案。我觉得,因为是对之前Fom Postback问题的处理方式导致的这个bug,所以在坚持目前方式的前提下,这个bug是没法修复的。

我一直是使用UrlRewritingNet.UrlRewrite的,直到最近发现了这个cross page postback的bug后。要解决这个问题,只能是采用与UrlRewriter.NET一样的方式。具体是,在源码中去除对Page.PreInit的处理,就是去掉下面的代码。然后,也重写一个Form控件来替代内置的Form。
private void OnAppPreRequestHandlerExecute(object sender, EventArgs e)
     {
         HttpApplication app = sender as HttpApplication;
         System.Web.UI.Page page = app.Context.CurrentHandler as System.Web.UI.Page;
         if (page != null)
         {
             page.PreInit += new EventHandler(OnPagePreInit);
         }
     }

我又尝试了一下UrlRewriter.NET,首先还没有发现它有bug,在URL匹配规则的定义上,它也要更灵活和强大,支持规则的分组,这在规则多时可以提高匹配效率。此外作者一直在更新维护,文档帮助也比较完整,而UrlRewritingNet.UrlRewrite早就没有更新了。但是对于自定义的query string的处理,以及对于物理存在的地址是否做重写的处理上,UrlRewritingNet.UrlRewrite来的更简单,全部是做内置处理了,而UrlRewriter.NET需要用户自己在定义规则时考虑这些问题,不过作者也都给出了大部分情况下的列子,用的时候千万别忘了看一下Common Rules

最后,个人还是推荐大家使用UrlRewriter.NET,毕竟它可以解决所有的问题,而且还没有bug(有些其他的问题是通过HTTP Module来处理URL重写的共同的问题)。当然,它用起来也是相对复杂一些。

抱歉!评论已关闭.