comportamento inconsistente com AJAX e ViewState em .NET

votos
2

Eu estou achando que apertar o botão Atualizar no meu navegador será temporariamente estragar o ViewState para controles dentro de um UpdatePanel.

Aqui está a minha situação: eu fiz um WebControl personalizado que armazena valores no ViewState. Eu coloquei este controle dentro de um UpdatePanel. Quando eu apertar o botão de refresh no meu navegador, ele irá temporariamente acabar com os valores no ViewState. No entanto, na próxima postagem, os valores que estavam no ViewState antes de eu bater refresh magicamente reaparecem.

Esse comportamento estraga meu WebControl. Após eu bater refresh, o controle é devolvido ao seu estado inicial, uma vez que o ViewState está vazio e IsPostBack é definida como falsa. No entanto, quando eu clicar em um dos controles de postagem dentro do meu WebControl, o WebControl irá recarregar com os mesmos valores que estavam no ViewState antes de eu bater refresh.

Estranhamente, isso só acontece quando estou usando AJAX. Quando meu controle está fora de um UpdatePanel, Firefox dá-me a sua mensagem padrão , Para exibir esta página, o Firefox deve enviar informações que irão repetir qualquer ação (como uma pesquisa ou confirmação de compra) que foi realizado anteriormente (Reenviar) (Cancelar) . Isso é bom, porque pelo menos o comportamento é consistente. No entanto, eu absolutamente deve usar AJAX para este projeto.

Então é isso que eu gostaria de fazer - Eu quero fazer o comportamento refresh consistente. Seria melhor se bater refresh não afetou o ViewState em tudo. Mas se tiver de acabar com o ViewState, tudo bem, contanto que o ViewState ESTADAS exterminada. Nenhum deste material com valores desaparecer e reaparecer.

Ah sim, e aqui está o meu código de exemplo:

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();
        }
    }
}
Publicado 09/12/2008 em 21:50
fonte usuário
Em outras línguas...                            


3 respostas

votos
1

Eu apenas re-ler sua pergunta e percebi que eu perdi alguma coisa ...

Você está acertando os navegadores botão atualizar!

Isso é um problema? SIM!

O que acontece quando você apertar o botão de atualização do navegador? Ele atualiza a página atual. Se houvesse uma nova postagem, ele irá reenviar os dados de postagem.

O retorno de chamada AJAX pode atualizar o ViewState na medida em que a página está em causa, mas apertar o botão de atualização do navegador irá re-post do velho ViewState.

Há uma riqueza está a discussão sobre o assunto que você pode Google.

Uma idéia muito simples é talvez armazenar as informações em estado de sessão em vez talvez. Isso também pode também ter sua própria emissão também, é claro. Mas pode atingir o seu objetivo imediato.

Uma dica para limpar a história de um postback (para evitar a re-post) é redirecionar de volta para a mesma página novamente.

Respondeu 12/12/2008 em 14:19
fonte usuário

votos
1

Tente o seguinte ...

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

Basicamente derivada do código de cima do Método Control.LoadViewState e Método Control.SaveViewState de MSDN.

Respondeu 10/12/2008 em 00:27
fonte usuário

votos
0

Seu ViewState não está sendo salvo. A substituição SaveViewState é para salvar objetos, não para colocar coisas dentro do saco de ViewState. O saco ViewState já está além do ponto de mnarking coisas sujas e as alterações feitas não serão persistentes. Você precisa criar uma matriz de objeto para carregar / visualizar as informações de ViewState.

Faça o que BlackMael mostra.

Respondeu 10/12/2008 em 00:32
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more