我发现点击浏览器上的“刷新”按钮会暂时搞砸UpdatePanel中控件的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 :(得分: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;
}
基本上来自MSDN的Control.LoadViewState Method和Control.SaveViewState Method上面的代码。
答案 1 :(得分:1)
我只是重新阅读你的问题并意识到我错过了一些东西......
您正在点击浏览器刷新按钮!
这是一个问题吗? 是<!/强>
点击浏览器上的刷新按钮会发生什么? 它会刷新当前页面。如果有回发,它将重新发送帖子数据。
就页面而言,AJAX回调可能会更新ViewState,但点击浏览器刷新按钮将重新发布旧的ViewState。
有关此问题的讨论很丰富,你可以谷歌。
一个非常简单的想法可能是将信息存储在会话状态中。当然,这也有其自身的问题。但它可能会实现您的直接目标。
用于擦除回发历史记录(以防止重新发布)的提示是重新定向到同一页面。
答案 2 :(得分:0)
您的ViewState未被保存。 SaveViewState覆盖用于保存OBJECTS,而不是用于将东西放入ViewState包中。 ViewState包已经超出了肮脏的东西,你所做的改变将不会被持久化。您需要创建一个对象数组来加载/查看ViewState信息。
执行BlackMael所显示的内容。