c# - .NET 中 AJAX 和 ViewState 的行为不一致

标签 c# .net ajax updatepanel viewstate

我发现点击浏览器上的“刷新”按钮会暂时搞砸 UpdatePanel 内控件的 ViewState。

这是我的情况:我制作了一个自定义 WebControl,它在 ViewState 中存储值。我将此控件放在 UpdatePanel 中。当我点击浏览器上的“刷新”按钮时,它会暂时清除 ViewState 中的值。但是,在下一次回发时,在我点击“刷新”之前 ViewState 中的值神奇地重新出现了。

这种行为搞砸了我的网络控制。在我点击“刷新”后,控件返回到其初始状态,因为 ViewState 为空并且 IsPostBack 设置为 false。但是,当我单击我的 WebControl 中的一个回发控件时,WebControl 将重新加载与我点击“刷新”之前 ViewState 中相同的值。

奇怪的是,这只发生在我使用 AJAX 时。当我的控件在 UpdatePanel 之外时,Firefox 给我它的标准消息,“要显示此页面,Firefox 必须发送将重复之前执行的任何操作(例如搜索或订单确认)的信息(重新发送)(取消) ”这很好,因为至少行为是一致的。但是,我绝对必须为此项目使用 AJAX。

所以这就是我想做的 - 我想让“刷新”行为保持一致。如果点击“刷新”根本不影响 ViewState,那将是最好的。但是,如果它必须清除 ViewState,那也没关系,只要 ViewState 保持清除状态即可。这些东西的值(value)都不会消失和重现。

哦,是的,这是我的示例代码:

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

最佳答案

我刚刚重新阅读了您的问题并意识到我错过了一些东西...

您正在点击浏览器刷新按钮!

这是个问题吗? 是的!

当您点击浏览器上的刷新按钮时会发生什么? 它刷新当前页面。如果有回发,它将重新发送发布数据。

就页面而言,AJAX 回调可能会更新 ViewState,但点击浏览器刷新按钮将重新发布旧的 ViewState。

您可以在 Google 上对此事进行大量讨论。

一个非常简单的想法可能是将信息存储在 session 状态中。当然,那也可能有其自身的问题。但它可能会实现您的近期目标。

删除回发历史记录(以防止重新发布)的一个技巧是再次重定向回同一页面。

关于c# - .NET 中 AJAX 和 ViewState 的行为不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/354195/

相关文章:

javascript - 如何在mvc中将变量传递给模型的属性

c# - 在 AutoFixture 自定义上调用 Dispose 方法

c# - 将语音转换为文本 C#

.net - CheckListBox - 根据数组值检查项目 - VB.NET

.net - SQL Server 2005事务级别和存储过程

javascript - 使用 JS 检查输入的 mysql DB

php - Jquery Ajax POST 请求失败

c# - 创建列表后如何更新 Xamarin Forms ListView 的 ViewCell 属性?

c# - 条码字体与其他条码库的区别

c# - 写入 CSV 文件