Непоследовательное поведение с AJAX и ViewState в .NET - PullRequest
2 голосов
/ 09 декабря 2008

Я обнаружил, что нажатие кнопки "Обновить" в моем браузере временно испортит ViewState для элементов управления внутри UpdatePanel.

Вот моя ситуация: я создал собственный WebControl, который хранит значения в ViewState. Я поместил этот элемент управления в UpdatePanel. Когда я нажимаю кнопку «обновить» в моем браузере, он временно стирает значения в ViewState. Однако при следующей обратной передаче значения, которые были в ViewState до того, как я нажал «обновить», волшебным образом появляются снова.

Такое поведение портит мой веб-контроль. После нажатия кнопки «обновить» элемент управления возвращается в исходное состояние, поскольку 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();
        }
    }
}

Ответы [ 3 ]

1 голос
/ 12 декабря 2008

Я просто перечитал твой вопрос и понял, что что-то упустил ...

Вы нажимаете браузеры кнопку обновления!

Это проблема? ДА!

Что происходит, когда вы нажимаете кнопку обновления в браузере? Обновляет текущую страницу. Если произошла обратная передача, данные будут отправлены повторно.

Обратный вызов AJAX может обновлять ViewState, если это касается страницы, но нажатие кнопки обновления браузера приведет к повторной публикации старого ViewState.

Существует богатство дискуссии по этому вопросу, которую вы можете Google.

Одна очень простая идея - возможно, вместо этого хранить информацию в состоянии сеанса. Это тоже тоже может иметь свою проблему, конечно. Но это может достичь вашей непосредственной цели.

Подсказка для удаления истории обратной передачи (для предотвращения повторной публикации) состоит в том, чтобы снова перенаправить обратно на ту же страницу.

1 голос
/ 10 декабря 2008

Попробуйте следующее ...

    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 и метода Control.SaveViewState из MSDN.

0 голосов
/ 10 декабря 2008

Ваш ViewState не сохраняется. Переопределение SaveViewState предназначено для сохранения ОБЪЕКТОВ, а не для помещения вещей в пакет ViewState. Сумка ViewState уже выходит за рамки грязных вещей, и внесенные вами изменения не будут сохранены. Вам нужно создать массив объектов для загрузки / просмотра информации ViewState.

Делайте то, что показывает BlackMael.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...