2008-12-09 39 views
2

我發現點擊瀏覽器上的「刷新」按鈕會暫時使UpdatePanel中的控件的ViewState失效。與.NET中的AJAX和ViewState的行爲不一致

這是我的情況:我做了一個自定義的WebControl,它將值存儲在ViewState中。我把這個控件放在UpdatePanel裏面。當我點擊瀏覽器上的「刷新」按鈕時,它會暫時清除ViewState中的值。但是,在下一個回傳中,在我點擊「刷新」之前,ViewState中的值奇蹟般重現。

這種行爲搞砸了我的webcontrol。在我點擊「刷新」後,控件返回到它的初始狀態,因爲ViewState是空的並且IsPostBack設置爲false。但是,當我點擊WebControl中的一個回發控件時,WebControl將在我點擊「刷新」之前用與ViewState中相同的值重新加載。

奇怪的是,這隻發生在我使用AJAX時。當我的控件位於UpdatePanel之外時,Firefox會給我一個標準的消息,「要顯示此頁面,Firefox必須發送將重複之前執行的任何操作(例如搜索或訂單確認)的信息(重新發送)(取消) 「。這很好,因爲至少行爲是一致的。但是,我絕對必須爲這個項目使用AJAX。

所以這就是我想要做的 - 我想使「刷新」行爲一致。如果點擊「刷新」根本不影響ViewState將是最好的。但是,如果必須清除ViewState,那很好,只要ViewState STAYS消失。沒有任何東西的價值消失和重現。

噢,這是我的示例代碼:

using System; 
using System.Data; 
using System.Configuration; 
using System.Linq; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.HtmlControls; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Xml.Linq; 

namespace TestControls 
{ 
    public class TestControl : WebControl 
    { 
     int _clickCount; 
     bool _mustUpdate; 

     protected override void LoadViewState(object savedState) 
     { 
      base.LoadViewState(savedState); 

      _clickCount = ((int)ViewState["clickCount"]); 
      _mustUpdate = ((bool)ViewState["mustUpdate"]); 
     } 

     protected override void OnLoad(EventArgs e) 
     { 
      base.OnLoad(e); 

      Controls.Clear(); 
      ControlCreator(); 
     } 

     private void ControlCreator() 
     { 
      Label tempLabel = new Label(); 
      LiteralControl tempLiteral = new LiteralControl("<br/><br/>"); 
      LinkButton tempLink = new LinkButton(); 

      tempLink.ID = "testLink"; 
      tempLink.Text = "Click me!"; 
      tempLink.Click += new EventHandler(tempLink_Click); 

      tempLabel.ID = "testLabel"; 
      tempLabel.Text = _clickCount.ToString(); 

      Controls.Add(tempLabel); 
      Controls.Add(tempLiteral); 
      Controls.Add(tempLink); 
     } 

     void tempLink_Click(object sender, EventArgs e) 
     { 
      _clickCount++; 
      _mustUpdate = true; 
     } 

     protected override void OnPreRender(EventArgs e) 
     { 
      base.OnPreRender(e); 

      if (_mustUpdate) 
      { 
       Controls.Clear(); 
       ControlCreator(); 

       _mustUpdate = false; 
      } 
     } 

     protected override object SaveViewState() 
     { 
      ViewState["clickCount"] = _clickCount; 
      ViewState["mustUpdate"] = _mustUpdate; 

      return base.SaveViewState(); 
     } 
    } 
} 
+0

你的更新面板設置爲條件刷新?您可能想要追蹤控件生命週期中的突出事件。正如你所說的,當你使用更新面板時,問題就開始了。 – Perpetualcoder 2008-12-09 22:12:05

回答

1

我只是重讀你的問題,並意識到我錯過了一些東西......

你擊中瀏覽器刷新按鈕!

這是問題嗎? 是的!

當您點擊瀏覽器上的刷新按鈕時會發生什麼? 它刷新當前頁面。如果有回傳,它會重新發送發佈數據。

Ajax回調可以儘可能的頁面來說卻擊中瀏覽器刷新按鈕將重新發布的舊的ViewState更新的ViewState。

關於您可以谷歌的事情有一個財富是討論。

一個非常簡單的想法是,也許可能將信息存儲在Session狀態中。當然,這也有其自身的問題。但它可能會實現您的直接目標。

擦除回發歷史(以防止重新發布)的提示是再次重定向回到同一頁面。

+0

實際上,我確實有最後一個問題 - 我明白爲什麼點擊「刷新」會消除Viewstate ....但爲什麼點擊我的LinkBut​​tons之一會帶回ViewState中「refresh?」之前的值。這是真正莫名其妙的部分。 – user44701 2008-12-12 18:48:25

1

請嘗試以下...

protected override void LoadViewState(object savedState) 
    { 
     if (savedState != null) 
     { 
      object[] myState = (object[])savedState; 

      if (myState[0] != null) base.LoadViewState(myState[0]); 
      if (myState[1] != null) _clickCount = ((int)myState[1]); 
      if (myState[2] != null) _mustUpdate = ((bool)myState[2]); 
     } 
    } 

    protected override object SaveViewState() 
    { 
     object[] allStates = new object[3]; 

     allStates[0] = base.SaveViewState(); 
     allStates[1] = _clickCount; 
     allStates[2] = _mustUpdate; 

     return allStates; 
    } 

基本上從Control.LoadViewState Method和MSDN Control.SaveViewState Method得出上面的代碼。

0

您的ViewState沒有被保存。 SaveViewState覆蓋用於保存OBJECTS,而不是將東西放入ViewState包中。 ViewState包已經超出了骯髒的東西,你所做的更改不會被持續。您需要創建一個對象數組來加載/查看ViewState信息。

做什麼BlackMael顯示。