Я обнаружил, что нажатие кнопки «Обновить» в моем браузере временно приводит к сбоям в работе ViewState для элементов управления внутри UpdatePanel.
Вот моя ситуация: я создал собственный WebControl, который хранит значения в ViewState. Я поместил этот элемент управления в UpdatePanel. Когда я нажимаю кнопку «Обновить» в своем браузере, он временно стирает значения в ViewState. Однако при следующей обратной передаче значения, которые были в ViewState до того, как я нажал «обновить», волшебным образом снова появятся.
Такое поведение портит мой веб-контроль. После того, как я нажму «обновить», элемент управления возвращается в исходное состояние, поскольку ViewState пуст, а IsPostBack имеет значение false. Однако, когда я нажимаю один из элементов управления обратной передачей в моем WebControl, WebControl перезагружается с теми же значениями, которые были в ViewState до того, как я нажму «обновить».
Как ни странно, это происходит только тогда, когда я использую AJAX. Когда мой контроль находится за пределами UpdatePanel, Firefox выдает мне стандартное сообщение: «Чтобы отобразить эту страницу, Firefox должен отправить информацию, которая повторит любое действие (например, поиск или подтверждение заказа), которое было выполнено ранее (Повторная отправка) (Отмена) . " Это нормально, потому что, по крайней мере, поведение единообразно. Однако мне абсолютно необходимо использовать AJAX для этого проекта.
Итак, это то, что я хотел бы сделать - я хочу, чтобы поведение «обновления» было согласованным. Было бы лучше, если бы нажатие кнопки «обновить» вообще не влияло на ViewState. Но если ему нужно стереть ViewState, это нормально, пока ViewState ОСТАЕТСЯ уничтоженным. Ничего подобного с исчезновением и появлением значений.
Ах да, а вот мой пример кода:
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();
}
}
}





Попробуйте следующее ...
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.
Ваше ViewState не сохраняется. Переопределение SaveViewState предназначено для сохранения ОБЪЕКТОВ, а не для помещения вещей в пакет ViewState. Пакет ViewState уже выходит за рамки того, что можно пометить как грязный, и внесенные вами изменения не сохранятся. Вам необходимо создать массив объектов для загрузки / просмотра информации ViewState.
Делайте то, что показывает BlackMael.
Я просто перечитал ваш вопрос и понял, что что-то упустил ...
Вы нажимаете кнопку обновления браузеры!
Это проблема? ДА!
Что происходит, когда вы нажимаете кнопку обновления в браузере? Обновляет текущую страницу. Если была обратная передача, он повторно отправит данные публикации.
Обратный вызов AJAX может обновить ViewState, насколько это касается страницы, но нажатие кнопки обновления браузера приведет к повторной публикации старого ViewState.
Существует множество дискуссий по этому поводу, которые вы можете найти в Google.
Одна очень простая идея - возможно, вместо этого сохранить информацию в состоянии сеанса. Конечно, это тоже может иметь свои проблемы. Но он может достичь вашей ближайшей цели.
Совет по стиранию истории обратной передачи (чтобы предотвратить повторную публикацию) - снова перенаправить обратно на ту же страницу.
На самом деле, у меня есть последний вопрос - я понимаю, почему нажатие «обновить» приведет к стиранию Viewstate ... но почему нажатие одной из моих LinkButton вернет значения, которые были в ViewState до «обновления»? Это настоящая необъяснимая часть.
Настроена ли ваша панель обновления для условного обновления? Возможно, вы захотите отследить важные события в жизненном цикле вашего элемента управления. Как вы уже сказали, проблемы начинаются при использовании панели обновлений.