zoukankan      html  css  js  c++  java
  • 使用UrlRewriter进行Url重写的完整解决方案

    转自:http://www.cnblogs.com/mouhong-lin/archive/2008/08/07/1262965.html

    Setp 1:

    下载UrlRewriter => http://urlrewriter.net/

    Setp 2:

    解压后将其\bin\Release\的Intelligencia.UrlRewriter.dll添加到Web项目的Bin目录下

    Setp 3:

    配置:打开web.config,在configSecions中添加sectionHandler:

    <section name="rewriter" requirePermission="false" type="Intelligencia.UrlRewriter.Configuration.
    RewriterConfigurationSectionHandler, Intelligencia.UrlRewriter"
     />

    添加这个section是为了它能够处理web.config中的节;然后对UrlRewriter配置url重写规则:

    <rewriter>
        
    <rewrite url=”~/lmh$” to=”~/Users.aspx?user=lmh” processing=”stop” />
    </rewriter>

    url是可以使用正则表达式的。比如上面的例子,就是将http://www.***.net/lmh重写到http://www.***.net/Users.aspx?user=lmh,$在正则表达式中表示是串的结束,也就是说http://www.***.net/lmhe是不会被重写到to后的地址的,如果把$去掉则可以。

    Setp 4:

    使rewriter生效:UrlRewriter是在HttpModule中做url重写的,要使重写生效,就得先把HttpModule添加到web.config中:

    <httpModules>
        
    <add name="UrlRewriter" type="Intelligencia.UrlRewriter.RewriterHttpModule, Intelligencia.UrlRewriter"/>
    </httpModules>

    Setp 5:

    让ReWriter有机会重写Url: 当iis收到一个请求时,并不是都会扔给asp.net(aspnet_isapi.dll)来处理,比如静态html,默认情况下,当请求html页面时,iis直接就把结果抛给了客户端,之所以.aspx页面会被asp.net引擎处理,是因为在iis有进行处理程序映射,.aspx被映射到aspnet_isapi.dll,所以当iis收到请求时,先看后缀名,如果是aspx,那就把它交给aspnet_isapi.dll来处理。因为UrlRewriter是asp.net级别的重写组件,所以,假如要想执行setp3中例子那样的重写,得先让UrlRewriter有机会收到这个地址的请求才行(默认UrlRewriter是没机会处理这个url的,因为iis收到这个地址的请求时,因为它没有映射到aspnet_isapi.dll,所以会直接抛出404找不到的错误,因此,要替它做这个映射。打开iis,在属性中有这一项,我们可以让*映射到aspnet_isapi.dll,这样所有的文件都交给asp.net来处理了,UrlRewriter也就有机会出手了。
    配置方法:
    IIS配置:网站->属性->虚拟目录->配置(G)...->映射->通配符应用程序映射->添加
    可执行文件:c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll
    扩展名为:.html
    确认文件是否存在:不选.

    如果用的是IIS7.0,则不用这么麻烦,整个Setp4可以简化为:在web.config中的节的节中添加上UrlRewriter:

    <add name="UrlRewriter" type="Intelligencia.UrlRewriter.RewriterHttpModule, Intelligencia.UrlRewriter"/>

    这会保证所有的请求都会经过asp.net的这个Module。

    现在,重写就算基本完成了,但有几个问题:

    Problem 1:

     图片可能不显示:如果进行Url Rewirte并且页面中的图片引用是使用相对路径的话,很可能会发现图片无效了,这是因为,假如/Users/lmh会被重写为/Users.aspx?user=lmh,而Users.aspx上有一张图片,放在相同目录下:logo.gif,(Users.aspx中是<img src='logo.gif' />)那当请求/Users/lmh时,浏览器对logo.gif的请求的路径将变成/Users/logo.gif,而实际上logo.gif是要用/logo.gif才能请求得到的,所以,为了保证Url rewrite后不会出现这个问题,需要使用<img src='/logo.gif' />,但是当使用UrlRewriter时,对于Css,如果代码中是,而实际用Users/lmh去请求的话,会发现其实已经变成了,而图片,如果是用的服务器控件的话,也可以继续使用相对路径,就不存在标题中的问题。

    Problem 2:

    Asp.net的postback会导致真实地址又被嚗光:还是setp3的例子,假设Users.aspx中有一个服务器按钮控件,当第一次请求时,确实OK,但是一旦点击了那个按钮,地址栏又变成了http://www.***.net/Users.aspx?user=lmh,原因是asp.net的服务器form控件的action默认都是指定当前页面地址的,虽然我们收到的请求是…/lmh,但经过UrlRewrite后,asp.net处理的已经是真实的地址:…/Users.aspx?user=lmh,所以在form被Render时,action会是../Users.aspx?user=lmh,那么,要解决这个问题,就是让form的action的值也被render为请求的地址,这个网上已经有答案了,就是利用ControlAdapter(写在App_Code中即可,不过为了重用,可以放到类库项目中):

    FormRewriterControlAdapter    public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter
     2    {
     3        protected override void Render(HtmlTextWriter writer)
     4        {
     5            base.Render(new RewriteFormHtmlTextWriter(writer));
     6        }

     7    }

     8 
     9    public class RewriteFormHtmlTextWriter : HtmlTextWriter
    10    {
    11        public RewriteFormHtmlTextWriter(HtmlTextWriter writer)
    12            : base(writer)
    13        {
    14            this.InnerWriter = writer.InnerWriter;
    15        }

    16 
    17        public override void WriteAttribute(string name, string value, bool fEncode)
    18        {
    19            if (name == "action")
    20            {
    21                HttpContext context = HttpContext.Current;
    22 
    23                value = context.Request.RawUrl;
    24            }

    25             base.WriteAttribute(name, value, fEncode);
    26        }

    27    }

    这段代码是来自Jeffery Zhao的博客文章(我去掉了其中一些代码,只保留了保证会工作的最基本代码)。

    需要说明的一点是:HtmlTextWriter有两个WriteAttribute方法:

    public virtual void WriteAttribute(string name, string value, bool fEncode)

    public virtual void WriteAttribute(string name, string value)

    重写下面的那个WriteAttribute是不能成功的,必须重写上面那个方法。为什么呢?先调试看看。

    会发现如果重写的是上面那个方法,则会有一次传进来的name值是"action",如我所愿,而重写下面那个方法则没发现传进来值是”action”的name参数。这是怎么搞的?

    首先我们要知道,下面那个方法其实是简单的调用了上面的WriteAttribute :

    public virtual void WriteAttribute(string name, string value) {

          WriteAttribute(name, value, false /*encode*/);

    }

    这是framework中的源码。那么,我们所可以猜测到的,就是action这个属性不是通过调用WriteAttribute(“action”, “…”)来渲染的,而是直接调用WrtiteAttribute(“action”, “…”, …),那我们就打开HtmlForm的源代码看看吧(没有源代码的可以用Reflector看),找到HtmlForm.RenderAttributes(HtmlTextWrtier writer)方法,其中有几行:

    writer.WriteAttribute("method", Method);

    Attributes.Remove("method");

    // Encode the action attribute - ASURT 66784

    writer.WriteAttribute("action", GetActionAttribute(), true /*encode*/);

    Attributes.Remove("action");

    我们重点看的是上面加粗并下划线的那两行,可以很清楚的看到,当渲染”method”属性时,只是调用了

    public virtual void WriteAttribute(string name, string value)

    而渲染action属性则是调用了

    public virtual void WriteAttribute(string name, string value, bool fEncode)

    那么,答案也就浮出水面了。

    接下来,我们要让这个Adapter起作用(上面之所以可以调试,是因为我已经让其起作用了,只是还没写出来)。添加Asp.net Folder:App_Browses,新建一个browser文件:

    <browsers>

        <browser refID="Default">

          <controlAdapters>

            <adapter controlType="System.Web.UI.HtmlControls.HtmlForm"

                     adapterType="FormRewriterControlAdapter"/>

          </controlAdapters>

        </browser>

    </browsers>

    因为上面的FormRewriterControlAdapter是写在App_Code中的,所以不需要添加命名空间。

    上面说的是一种防止postback后地址还原的办法,还有一种办法就是利用UrlRewriter自带的form控件,这个方法还不需要写这么多代码:

    首先,要先注册控件:

    <%@ Register Namespace="Intelligencia.UrlRewriter" Assembly="Intelligencia.UrlRewriter" TagPrefix="rewriter" %>

    然后用<rewriter:form runat="server"></form>代替掉原来的<form runat="server"></form>就可以了。

    这么一来,使用UrlRewriter进行asp.net级别的UrlRewrite就弄好了。

    参考文章:

    // 重提URL Rewrite(2):使用已有组件进行URL Rewrite
    http://www.cnblogs.com/JeffreyZhao/archive/2008/01/13/Url-Rewrite-2.html


    // 配置IIS解析.html文件
    http://www.cnblogs.com/silverlight_team/archive/2009/03/11/1409209.html


    // 使用UrlRewriter进行Url重写的完整解决方案
    http://www.cnblogs.com/mouhong-lin/archive/2008/08/07/1262965.html


    // 常用的正规表示式
    http://weijie.blog.51cto.com/340746/89603


    // Intelligencia.UrlRewriter简单介绍
    http://www.cnblogs.com/sunshine-anycall/archive/2009/08/05/1539972.html


    // Intelligencia.UrlRewriter.dll重写URL的规则例子
    http://zhoude3.blog.163.com/blog/static/6828188020091074244919/ 

  • 相关阅读:
    Construct Binary Tree from Preorder and Inorder Traversal
    Construct Binary Tree from Inorder and Postorder Traversal
    Maximum Depth of Binary Tree
    Sharepoint 2013 创建TimeJob 自动发送邮件
    IE8 不能够在Sharepoint平台上在线打开Office文档解决方案
    TFS安装与管理
    局域网通过IP查看对方计算机名,通过计算机名查看对方IP以及查看在线所有电脑IP
    JS 隐藏Sharepoint中List Item View页面的某一个字段
    SharePoint Calculated Column Formulas & Functions
    JS 两个一组数组转二维数组
  • 原文地址:https://www.cnblogs.com/wangpei/p/1597543.html
Copyright © 2011-2022 走看看