国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

UpdatePanel與UrlRewrite

2019-11-18 16:46:29
字體:
來源:轉載
供稿:網友

  今天收到郵件,被問及為什么UpdatePanel如果結合了UrlRewrite就會出現問題。一開始我不以為然,由于我也曾經在UrlRewrite時使用過UpdatePanel,沒有出現過問題。但是收到對方打包的代碼后,發現這個問題的確重現了,如果直接訪問目標頁面就不會有任何問題。因為當時在公司,沒有仔細地去研出錯的原因。在回家的路上,腦子里一遍一遍地模擬著UpdatePanel的實現過程,卻沒有察覺到有任何不妥。最后還是忍不住,坐在公交車上的時候就打開筆記本,仔細的尋找問題所在。公交車實在晃得厲害,還好最終在我嘔吐之前找到了問題,剛才的思考還是棋差一著。

 
重現問題:

  現在我將重現那個問題。在原來的代碼中使用了NBear的UrlRewriteModule,為了簡單起見,我使用了最普通的UrlRewrite的做法來得到相同的效果,盡量避免有些朋友(包括我)因為不熟悉NBear而妨礙文章內容的理解。

  首先,新建一個asp.net Ajax Enabled Web Site。創建一個文件~/SubFolder/Target.aspx,內容如下:

~/SubFolder/Target.aspx
<html xmlns="<head runat="server">
    <title>Target Page</title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:Scr
iptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
       
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <%= DateTime.Now.ToString() %>
                <asp:Button ID="Button1" runat="server" Text="Refresh" />
            </ContentTemplate>
        </asp:UpdatePanel>
    </form>
</body>
</html>
 

  然后再創建一個Global.asax,提供application_BeginRequest方法,在其中實現Url Rewrite,如下:

Global.asax中Application_BeginRequest方法
void Application_BeginRequest(object sender, EventArgs e)
{
    HttpContext context = (sender as HttpApplication).Context;
    if (context.Request.Path.Contains("Source.aspx"))
    {
        context.RewritePath("SubFolder/Target.aspx", false);
    }
}
 

  這樣,當我們訪問~/Source.aspx文件時,則會被Rewrite至~/SubFolder/Target.aspx,打開頁面,一切正常:


  點擊Refresh按鈕之后,時間被更新了。然后當我們再點擊按鈕之后,錯誤發生了:“Sys.WebForms.PageRequestManagerServerErrorException: An unknown eror occurred while PRocessing the request on the server. The status code returned from the server was: 12031”。

 

分析問題:

  發生這個問題的原因是因為Url Rewrite更新了Form提交的地址,而UpdatePanel又將這地址的改變反映到了頁面上。

  在第一次打開頁面時,我們可以看到頁面的源文件中<form />元素的action已經不是我們訪問的Source.aspx,而是Url Rewrite后的目標文件:

form元素的action為目標頁面
...
<form name="form1" method="post" action="SubFolder/Target.aspx" id="form1">
...
</form>
...

  還好我們使用了Partial Rendering,只要“目標”是正確的,UpdatePanel依舊能夠正確地發送和獲取數據,然后更新頁面。因此,在點擊Refresh按鈕之后,頁面被正確更新了。可是,我們form元素的action也變了,使用Web Development Helper和IE Dev Toolbar便一目了然:


  由于我們在進行異步PostBack時,直接訪問了~/SubFolder/Target.aspx,因此在生成的Form對象其action值為Target.aspx。于是乎,UpdatePanel兢兢業業地將客戶端form元素的action也進行了修改。這樣就讓我們再次提交時訪問了一個不存在的頁面,錯誤就再所難免了。

 

解決問題:

  既然發現了問題所在,那么解決起來自然也會得心應手。我們只要在響應Sys.Application的load事件即可,它會在頁面第一次加載時,以及每次Partial Rendering之后被觸發,我們在這時候修改頁面中form元素的action屬性即可,如下:

相應Sys.Application的load事件
Sys.Application.add_load(function()
{
    var form = Sys.WebForms.PageRequestManager.getInstance()._form;
    form._initialAction = form.action = window.location.href;
});
 
  至于為什么應該這樣獲得頁面中的form元素,_initialAction又是什么,以及為什么要設置它,就要牽涉到UpdatePanel的實現方式,在這里就不多作解釋了。只要頁面中放置了這么一小段代碼,這個問題就被解決了。

 

深入問題:

  造成這個問題的原因,其實就是因為在Url Rewrite之后,form元素的action并非客戶端請求的地址,而是Url Rewrite的目標地址。如果我們沒有使用Partial Rendering,而是使用了最傳統的PostBack,雖然不會造成頁面功能的破壞,但是在PostBack之后,用戶就會發現地址欄的內容變了,直接變成了目標地址。這可不是我們希望看到的結果,既然Rewrite了,就把它Rewrite到底。當然,我們依然可以使用上面提到的辦法,使用javaScript來修改form元素的action,但是這個做法實在不夠“美觀大方”,而且用戶從HTML源文件中也可以看到我們Url Rewrite的目標地址,不是嗎?

  如果我們能夠在服務器端設置Form的action就好了,可惜System.Web.UI.HtmlControls.HtmlForm類不允許我們這么做。不過還好,我們用的是ASP.NET,我們用的是面向對象的編程模型。于是我們“繼承”System.Web.UI.HtmlControls.HtmlForm,實現一個自己的Form控件:

繼承HtmlForm類實現自己的From
namespace ActionlessForm {
    public class Form : System.Web.UI.HtmlControls.HtmlForm
    {
        protected override void RenderAttributes(HtmlTextWriter writer)
        {
            writer.WriteAttribute("name", this.Name);
            base.Attributes.Remove("name");
            writer.WriteAttribute("method", this.Method);
            base.Attributes.Remove("method");
            this.Attributes.Render(writer);
            base.Attributes.Remove("action");
            if (base.ID != null)
            writer.WriteAttribute("id", base.ClientID);
        }
    }
}
 
 

  然后我們就可以在頁面中使用它了。當然,在這之前,我們需要在頁面(或Web.config)里注冊它:

使用我們自己實現的Form
<%@ Register TagPrefix="skm" Namespace="ActionlessForm"
    Assembly="ActionlessForm" %>
...
<skm:Form id="Form1" method="post" runat="server">
...
</skm:Form>
...
 

  至此,我們已經不需要在頁面里編寫一段“巧妙”的Javascript了,Url Rewrite之后form元素的action問題被解決了。

  (“深入問題”參考了MSDN上一篇文章的部分內容:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/urlrewriting.asp
http://m.survivalescaperooms.com/JeffreyZhao/archive/2006/12/27/updatepanel_with_url_rewrite.html


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 古田县| 江孜县| 曲麻莱县| 蒙自县| 泗阳县| 会昌县| 大理市| 大连市| 项城市| 蒲城县| 上饶县| 崇州市| 安康市| 佳木斯市| 沙坪坝区| 房山区| 苏州市| 克山县| 虞城县| 二连浩特市| 洛扎县| 赣榆县| 浪卡子县| 武隆县| 龙里县| 台南市| 左权县| 五峰| 洞头县| 琼中| 阳信县| 仁寿县| 昭平县| 上犹县| 乌拉特后旗| 泗水县| 名山县| 镇原县| 车险| 武强县| 阜宁县|