• 使用Microsoft Url Rewrite Module 进行URL重写以及Postback之后保持URL的解决方案


      Microsoft URL Rewrite Module 是微软推出的asp.net url重写模块,仅支持IIS7,要在IIS6上进行url重写,可以采用一些第三方的模块,比如 urlrewriting.net。首先去下载Rewrite Module并安装。安装完毕后,在IIS管理工具中就会出现Url Rewrite图标。

    image

    双击你需要进行URL重写的网站或者虚拟目录的URL Rewrite按钮,可以进行规则的编辑。微软的重写模块非常强大,有很多功能,还可以自己写程序对其进行扩展。本文仅介绍最常用和实用的利用正则表达式进行重写。重写的基本原理是当服务器接收到一个请求的时候,利用正则表达式匹配当前输入的url,然后根据一个规则将这个url转换为实际的url。例如,我们要把 localhost/Game/game.aspx?ID=SomeName转换为 localhost/SomeName/,也就是每个游戏名都作为一个独立的目录。于是,我们要匹配输入的url的格式是 ([^/?]*)/$,这个正则表达式不包括根目录,例如localhost/,它的含义是所有非/和?的字符,并且以/结尾,按照我们的要求,它的实际地址是~/Game/game.aspx,参数是正则表达式中第一个圆括号匹配到的内容。实际的url中会用到这个正则表达式的反向引用。反向引用的格式是 {R:n},其中n是一个整数。n等于0的时候是整个正则表达式,n大于0的时候是从左往右数第n个捕获组的值。在这里个例子中,我们的实际url就是 Game/Game.aspx?ID={R:1}。对于正则表达式的反向引用不太熟悉的人,微软也提供了一个很方便的功能,Test Pattern

    image

    在这里可以很方便的测试自己的正则表达式是否正确。完成后,点击Apply,就完成了一条规则的设置。它会在web.config文件中添加如下内容:

    <system.webServer>   
     <rewrite>
            <rules>
                <rule name="Game">
                    <match url="([^/?]*)/$" />
                    <action type="Rewrite" url="Game/Game.aspx?ID={R:1}" appendQueryString="false" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>

    熟悉的话可以直接在web.config中修改,比较方便。不过,VS2008并没有智能提示,反而提示rewrite节错误。

    当有多条重写规则的时候,asp.net从上到下依次匹配,因此,如果我们有如下规则

        <rewrite>
            <rules>
              <rule name="News">
                <match url="News/$" />
                <action type="Rewrite" url="Game/News.aspx" appendQueryString="false" />
              </rule>
                <rule name="Game">
                    <match url="([^/?]*)/$" />
                    <action type="Rewrite" url="Game/Game.aspx?ID={R:1}" appendQueryString="false" />
                </rule>
            </rules>
        </rewrite>
    

    那么 localhost/News/将会被转换为 Game/News.aspx 而不是 Game/Game.aspx?ID=News。如果对正则表达比较熟悉,重写url是没什么困难的。

    最后讲一个很困扰的问题,也就是当实际的url中带有参数的时候,如果页面上某个控件执行了postback的操作,那么浏览器上的url又会重新带上参数,变成类似http://localhost/goldshop/Aion/?ID=Aion 的样子。这是因为IIS实际处理的页面还是那个带有参数的真实url,因此postback的时候还是回发到原始的url上。解决方案主要参考 Jeffery Zhao的博文重提URL Rewrite(3):在URL Rewrite后保持PostBack地址。主要想法就是利用一个Control Adapter改写html中form控件的输出方式。将它的action改成我们重写过后的url而不再是原始的url。这个Adapter的代码如下:

    using System.IO;
    using System.Web;
    using System.Web.UI;
    
    namespace Sample.Web.UI.Adapters
    {
        public class FormRewriterControlAdapter :
            System.Web.UI.Adapters.ControlAdapter
        {
            protected override void Render(HtmlTextWriter writer)
            {
                base.Render(new RewriteFormHtmlTextWriter(writer));
            }
        }
    
        public class RewriteFormHtmlTextWriter : HtmlTextWriter
        {
            public RewriteFormHtmlTextWriter(HtmlTextWriter writer)
                : base(writer)
            {
                this.InnerWriter = writer.InnerWriter;
            }
    
            public RewriteFormHtmlTextWriter(TextWriter writer)
                : base(writer)
            {
                this.InnerWriter = writer;
            }
    
            public override void WriteAttribute(string name, string value, bool fEncode)
            {
                if (name == "action")
                {
                    HttpContext context = HttpContext.Current;
    
                    if (context.Items["ActionAlreadyWritten"] == null)
                    {
                        value = context.Request.RawUrl;
                        context.Items["ActionAlreadyWritten"] = true;
                    }
                }
                base.WriteAttribute(name, value, fEncode);
            }
        }
    }

    把这个代码放到App_Code文件夹中,另外在 App_Browser文件夹中新建一个browser文件,内容如下:

    <browsers>
      <browser refID="Default">
        <controlAdapters>
          <adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
                   adapterType="Sample.Web.UI.Adapters.FormRewriterControlAdapter" />
        </controlAdapters>
      </browser>
    </browsers>
    用来指定Control Adapter。这样就OK了。
  • 相关阅读:
    [NOIP2013提高组] CODEVS 3287 火车运输(MST+LCA)
    BZOJ 2763: [JLOI2011]飞行路线(最短路)
    BZOJ 1083: [SCOI2005]繁忙的都市(MST)
    USACO Seciton 5.4 Canada Tour(dp)
    HDOJ 3415 Max Sum of Max-K-sub-sequence(单调队列)
    POJ2823 Sliding Window(单调队列)
    USACO Section 5.4 TeleCowmunication(最小割)
    [IOI1996] USACO Section 5.3 Network of Schools(强连通分量)
    USACO Section 5.3 Milk Measuring (IDDFS+dp)
    USACO Section 5.3 Big Barn(dp)
  • 原文地址:https://www.cnblogs.com/yinzixin/p/1690627.html
Copyright © 2020-2023  润新知