<rewrite url="^/User/(/d+)$" to="~/User. " /> 欧美91看片特黄aaaa,日日天天久久,亚洲一区精品视频

色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

重提URL Rewrite(3):在URL Rewrite后保持PostBack地址

  在進(jìn)行了URL Rewrite之后,經(jīng)常會(huì)遇到的問題就是頁面中PostBack的目標(biāo)地址并非客戶端請求的地址,而是URL Rewrite之后的地址。以上一篇文章中的重寫為例:

<rewriter>
  <rewrite url="^/User/(/d+)$" to="~/User.ASPx?id=$1" processing="stop" />
  <rewrite url="^/User/(/w+)$" to="~/User.ASPx?name=$1" processing="stop" />
rewriter>

  當(dāng)用戶請求“/User/jeffz”之后,頁面中的出現(xiàn)的代碼卻會(huì)是

,這是因?yàn)樵谏纱a時(shí),頁面會(huì)使用當(dāng)前Request.Url.PathAndQuery的值來得到form元素的action。這導(dǎo)致了一旦PostBack,地址欄里就會(huì)出現(xiàn)“User.ASPx?name=jeffz”,而這個(gè)地址很可能是請求不到正確的資源的(因?yàn)榭赡鼙籖ewrite到了別處,或者由于目錄級(jí)別的關(guān)系而根本沒有該資源)。在之前《UpdatePanel與UrlRewrite》一文中,我說可以在頁面末尾添加一行JavaScript代碼來解決這個(gè)問題:

 

<script language="Javascript" type="text/Javascript">
    document.getElementsByTagName("form")[0].action = window.location;
script>

  這行代碼的意圖非常明顯,將form的action修改為window.location(即瀏覽器地址欄中的路徑),這樣當(dāng)頁面進(jìn)行PostBack時(shí),目標(biāo)地址就會(huì)是URL Rewrite之前的地址了。這種做法能夠讓程序正常運(yùn)行,但是實(shí)在不能讓我滿意。為什么?

  因?yàn)樘罅恕?/p>

  因?yàn)槲覀冞€是把URL Rewrite之后的地址暴露給了客戶端。用戶只要裝一個(gè)HTTP嗅探器(例如著名的Fiddler),或者在IE中直接選擇查看源文件,我們的目標(biāo)地址就毫無遮掩的顯示在用戶面前了。怎么能讓用戶知道我們的重寫規(guī)則?我們必須解決這個(gè)問題。解決的方法很簡單,也已經(jīng)非常流行了,那就是使用Control Adaptor來改變Form生成時(shí)的行為。不過讓我感到比較奇怪的是,關(guān)于這個(gè)Control Adaptor,在網(wǎng)絡(luò)上搜到的盡是VB.NET的版本,倒是微軟主推的C#語言卻找不到。雖然只要了解一點(diǎn)VB.NET的語法要改寫起來并不困難,但是畢竟也是個(gè)額外的工作啊。所以我現(xiàn)在就將這個(gè)Adaptor的C#版本代碼貼出來,以便朋友們能夠直接使用:

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

  簡單的說,這個(gè)Control Adaptor其實(shí)一直在等待“action”這個(gè)屬性被輸出的那一刻,將value變?yōu)楫?dāng)前Request對(duì)象的RawUrl屬性。這個(gè)屬性在ASP.NET剛接受到IIS傳來的請求時(shí)就確定了,它不會(huì)隨著接下來BeginRequest中的Rewrite操作而改變,因此我們只要為Form的action輸出RawUrl就可以解決PostBack地址改變這個(gè)問題了。

  不過要讓這個(gè)Control Adaptor生效,還必須在Web項(xiàng)目中創(chuàng)建一個(gè)browser文件,例如“App_Browsers/Form.browser”,在里面寫入如下代碼:

<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
               adapterType="Sample.Web.UI.Adapters.FormRewriterControlAdapter" />
    controlAdapters>
  browser>
browsers>

  至此,在ASP.NET層面上作URL Rewrite導(dǎo)致PostBack地址改變的問題已經(jīng)完美解決了——等等,為什么要強(qiáng)調(diào)“ASP.NET層面”?沒錯(cuò),因?yàn)槿绻贗IS層面上作URL Rewrite,這個(gè)問題依舊存在。例如您使用了IIRF做URL Rewrite,并讓上面的Control Adapter生效,還是會(huì)發(fā)現(xiàn)頁面上PostBack的地址和客戶端請求的地址不同。難道RawUrl也變得“不忠誠”了?這不是RawUrl的緣故,而是ASP.NET機(jī)制所決定的。為了解釋這個(gè)問題,我們重新看一下在第一篇文章《IIS與ASP.NET》中那幅示意圖:

  IIS級(jí)別的URL Rewrite發(fā)生在上面這幅圖中步驟2之前,正因?yàn)楸恢匦翿ewrite了,所以IIS的ISAPI選擇器才會(huì)將該請求交給ASPNET ISAPI處理。換句話說,當(dāng)IIS把請求交由ASP.NET引擎處理的時(shí)候,ASP.NET從IIS那里獲得的信息中已經(jīng)是URL Rewrite之后的地址了(例如/User.ASPx?name=jeffz),這樣無論在ASP.NET處理該請求的哪個(gè)環(huán)節(jié),都無法得知IIS當(dāng)初收到請求時(shí)的URL。

  也就是說,其實(shí)真沒辦法了。

  不過“真沒辦法”四個(gè)字是有條件的,完整地說應(yīng)該是:“靠ASP.NET自身”的確“真沒辦法”了。不過如果IIS在進(jìn)行URL Rewrite的時(shí)候幫我們一把,那么情況又會(huì)如何呢?IIRF作為一個(gè)成熟的開源組件,它自然知道ASP.NET引擎,乃至所有的ISAPI處理程序都需要它的幫助,它自然知道“改出手時(shí)就出手”的道理,因此它練就了將原始地址存放在服務(wù)器變量HTTP_X_REWRITE_URL之中的能力。不過IIRF也不會(huì)“自覺”地這么做(多累啊),這還要我們在配置文件中提醒它:

RewriteRule    ^/User/(/d+)$    /User.ASPx?id=$1      [I, L, U]
RewriteRule    ^/User/(/w+)$    /User.ASPx?name=$1    [I, L, U]

  請注意,我們使用了額外的Modifier。在Modifier集合中加入U(xiǎn)表明我們需要IIRF將URL Rewrite之前的原始地址存放在服務(wù)器變量HTTP_X_REWRITE_URL中。現(xiàn)在我們就可以在ASP.NET獲取到這個(gè)值了,于是我們將之前的Control Adapter代碼中的WriteAttribute方法作如下修改:

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.ServerVariables["HTTP_X_REWRITE_URL"]
                ?? context.Request.RawUrl;
            context.Items["ActionAlreadyWritten"] = true;
        }
    }
 
    base.WriteAttribute(name, value, fEncode);
}

  現(xiàn)在action的value已經(jīng)不是簡單地從RawUrl屬性中獲取了,而是設(shè)法從ServerVariables集合中取得HTTP_X_REWRITE_URL變量的值,因?yàn)槟抢锎娣帕薎IS所接受到的原始請求的地址。

  至此,有關(guān)URL Rewrite的主要話題已經(jīng)講完了,在下一篇,也就是本系列的最后一篇文章中,我們將重點(diǎn)看一下使用不同層面的URL Rewrite會(huì)在一些細(xì)節(jié)方面造成什么樣的區(qū)別,以及相關(guān)的注意點(diǎn)。

相關(guān)鏈接:

(1)IIS與ASP.NET

(2)使用已有組件進(jìn)行URL Rewrite

(4)不同級(jí)別URL Rewrite的一些細(xì)節(jié)與特點(diǎn)

NET技術(shù)重提URL Rewrite(3):在URL Rewrite后保持PostBack地址,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 扬中市| 花垣县| 湟中县| 乌兰察布市| 谷城县| 信宜市| 黑山县| 六安市| 开阳县| 通辽市| 宾川县| 屏东市| 陇川县| 仁寿县| 鲁甸县| 云梦县| 灌云县| 孝义市| 广河县| 铜川市| 梨树县| 成都市| 元氏县| 祁阳县| 介休市| 芜湖市| 宜昌市| 大悟县| 香港| 凤阳县| 调兵山市| 三河市| 永新县| 淮滨县| 南召县| 万荣县| 海口市| 婺源县| 武川县| 涡阳县| 邯郸市|