Prefácio
Contanto que você tenha um pouco de compreensão do ViewState, você saberá que o ViewState nas páginas Asp.net geralmente é armazenado em um campo oculto da página:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value=" Um monte de coisas bagunçadas">
Quando navegamos no arquivo fonte da página, vemos muitas coisas bagunçadas (principalmente quando a página possui um DataGrid com grande quantidade de dados, ou um GridView no ASP.NET 2.0). vez, isso é ViewState.
Conhecimento básico
Como há algumas novas mudanças no mecanismo de armazenamento de persistência do ViewState no ASP.NET 2.0, apresentarei brevemente os itens relevantes.
No ASP.NET 1.1, apenas o mecanismo de persistência do domínio oculto da página é fornecido, portanto, em alguns casos, você terá que desistir de usar o ViewState. Imagine se houver dezenas de milhares de registros no seu DataGrid (não pense. isso é anormal) Não há necessidade (alguém encontrou isso). Se o ViewState estiver ativado, você tem certeza de que o seu servidor IIS pode suportá-lo e a rede pode suportá-lo? Claro, você pode alterar seu mecanismo de armazenamento substituindo o método Page.SavePageStateToPersistenceMedium(), mas não se esqueça de substituir Page.LoadPageStateFromPersistenceMedium(), eles são um par.
O mecanismo de persistência de estado de exibição padrão no ASP.NET 2.0 ainda retém informações de estado como uma string codificada em Base64 em um elemento HTML oculto na página (um elemento com o atributo type definido como "oculto"). As páginas ASP.NET usam o objeto HiddenFieldPageStatePersister para executar esse trabalho e uma instância IStateFormatter para serializar e desserializar informações de estado do objeto. Ou, para clientes móveis com largura de banda e recursos limitados, você também pode usar a classe SessionPageStatePersister para armazenar o estado de visualização da página no objeto Session no servidor. Na verdade, há apenas mais um mecanismo de persistência de sessão. estado da página na sessão em vez de na página, o que representa uma economia de largura de banda.
Mas se você quiser ter uma compreensão mais profunda do mecanismo de persistência ViewState, você deve conhecer a classe abstrata PageStatePersister. Para reter o estado de visualização em um cliente que não pode suportar o mecanismo de persistência de estado de visualização existente, você pode estender a classe PageStatePersister e apresentar seu. próprios métodos de persistência de estado de visualização e você pode usar adaptadores de página para configurar aplicativos ASP.NET para usar diferentes mecanismos de persistência de estado de visualização com base no tipo de cliente para o qual a página é servida. As classes derivadas da classe PageStatePersister devem substituir o método abstrato Save para armazenar o estado de visualização e o estado de controle no meio de persistência e substituir o método Load para extrair informações de estado. Se você precisar serializar o estado de visualização e o estado de controle em strings, poderá usar o objeto IStateFormatter acessado por meio da propriedade StateFormatter. Ele serializa e desserializa com eficiência informações de estado do objeto em strings codificadas em Base64. Você também pode substituir a propriedade StateFormatter para fornecer seu próprio mecanismo de serialização de estado de objeto. Como fazer isso é explicado em meu código.
O
campo oculto
do mecanismo de persistência ViewStatenão será introduzido. Este é o campo padrão. Como afirmado no prefácio.
A sessão
só precisa substituir a propriedade PageStatePersister no ASP.NET2.0.
substituição protegida PageStatePersister PageStatePersister
{
pegar
{
retornar nova SessionPageStatePersister(Página);
}
}
Se você precisar substituir esses dois métodos de LoadPageStateFromPersistenceMedium no ASP.NET1.1:
objeto de substituição protegido LoadPageStateFromPersistenceMedium()
{
return Sessão["ViewState"];
}
substituição protegida void SavePageStateToPersistenceMedium (objeto viewState)
{
Sessão["ViewState"] = viewState;
RegisterHiddenField("__VIEWSTATE", "");
}
O banco de dados (meu exemplo é SQL Server2000)
está em ASP1.1. Por favor, preste atenção na linha roxa abaixo, não sei para que serve. . O código a seguir foi copiado do meu código-fonte. Você não precisa escrevê-lo assim, exceto os necessários.
substituição protegida void SavePageStateToPersistenceMedium (estado do objeto)
{
string viewStateID = "VIEWSTATE#" + Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
ClientScript.RegisterHiddenField("__VIEWSTATE_KEY",viewStateID);
ClientScript.RegisterHiddenField("__VIEWSTATE","");//Observe que
tente
{
if (losFormatter == null)
{
losFormatter = new LosFormatter();
}
StringWriter sw = new StringWriter();
losFormatter.Serialize(sw, estado);
Common.ViewStateData vsd = new ViewStateData();
vsd.ViewStateID = viewStateID;
vsd.ViewState = sw.ToString();
da = new DataAccess();
erro de string = da.SaveViewState(vsd);
Resposta.Write(erro);
}
pegar (exceção ex)
{
Response.Write(ex.Mensagem);
}
}
objeto de substituição protegido LoadPageStateFromPersistenceMedium()
{
string viewState = string.Empty;
tentar
{
if (losFormatter == null)
{
losFormatter = new LosFormatter();
}
string stateID = Page.Request["__VIEWSTATE_KEY"].ToString();
da = new DataAccess();
viewState = da.LoadViewState(stateID);
}
pegar
{}
return losFormatter.Deserialize(viewState);
}
Esta linha de código é basicamente OK em ASP2.0 Por que é básica? Porque é a linha acima ClientScript.RegisterHiddenField("__VIEWSTATE","")
; .net1.1 É viável. Também me referi ao código de outras pessoas e adicionei esta linha. Depois de adicionar esta linha, há apenas um <input type="hidden" name="__VIEWSTATE" value="" /> na
página. Existem duas dessas coisas no arquivo de origem da página após a execução
.
Não há problema em remover essa linha, então não entendo para que a instrução é usada. Diga-me claramente. Mas não funciona no Asp.net2.0. Ocorre o seguinte erro:
As informações de estado são inválidas para esta página e podem estar corrompidas.
De qualquer forma, fiquei confuso na época. e não consigo encontrar nada pesquisando no Google, sim, não sei se essa frase está errada. Estou deprimido há dois dias e o problema não pode ser resolvido. salvando o estado de visualização no banco de dados e lendo-o no banco de dados, não consegui encontrar o erro, então pensei no código várias vezes, mas fiquei um pouco confuso sobre por que a página deveria registrar uma linha oculta. campo de "__VIEWSTATE", então comentei esta linha e realmente funcionou. Então, ainda não entendo para que serve essa linha.
Claro, também podemos completar as funções acima escrevendo uma nova subclasse de PageStatePersister, que é nova no ASP.NET2.0:
namespace PageAdapter
{
usando o sistema;
usando System.IO;
usando System.Security.Permissions;
usando System.Web;
usando System.Web.UI;
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
classe pública DatabasePageStatePersister: PageStatePersister
{
public DatabasePageStatePersister (página da página): base (página)
{}
//
// Carrega ViewState e ControlState.
//
substituição pública void Load()
{
string viewState;
Formatador IStateFormatter = this.StateFormatter;
DataAccess da = new DataAccess();
string stateID = base.Page.Request["__VIEWSTATE_KEY"].ToString();
viewState = da.LoadViewState(stateID);
Par statePair = (Pair)formatter.Deserialize(viewState);
ViewState = statePair.First;
ControlState = statePair.Second;
}
//
// Persiste qualquer ViewState e ControlState.
//
substituição pública void Save()
{
if (ViewState! = Nulo || ControlState! = Nulo)
{
if (Page.Session! = Nulo)
{
string viewStateID = "VIEWSTATE#" + base.Page.Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
base.Page.ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
Par statePair = new Pair(ViewState, ControlState);
Formatador IStateFormatter = this.StateFormatter;
// Serializa o objeto statePair para uma string.
string serializedState = formatter.Serialize(statePair);
ViewStateData vsd = new ViewStateData();
vsd.ViewStateID = viewStateID;
vsd.ViewState = serializedState;
DataAccess da = new DataAccess();
erro de string = da.SaveViewState(vsd);
}
outro
throw new InvalidOperationException("Sessão necessária para StreamPageStatePersister.");
}
}
}
}
Então você pode substituir a propriedade PageStatePersister:
substituição protegida PageStatePersister PageStatePersister
{
pegar
{
retornar novo DatabasePageStatePersister(Página);
}
o arquivo
não é muito diferente do banco de dados, estou falando apenas do ASP.NET2.0. Deveria ser semelhante no ASP.NET1.1, mas não escrevi o código para depuração:
ainda uso o método. de escrever uma nova subclasse de PageStatePersister:
namespace StreamPageAdapter.
{
usando o sistema;
usando System.IO;
usando System.Security.Permissions;
usando System.Web;
usando System.Web.UI
;
// O StreamPageStatePersister é um exemplo de estado de visualização
// mecanismo de persistência que persiste na visualização e controle
// estado no servidor Web.
//
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
classe pública StreamPageStatePersister: PageStatePersister
{
public StreamPageStatePersister (página da página): base (página)
{}
//
// Carrega ViewState e ControlState.
//
substituição pública void Load()
{
Fluxo stateStream = GetSecureStream();
// Leia a string de estado, usando StateFormatter.
Leitor StreamReader = novo StreamReader(stateStream);
Formatador IStateFormatter = this.StateFormatter;
string fileContents = leitor.ReadToEnd();
// Deserilize retorna o objeto Pair que é serializado em
// o método Salvar.
Par statePair = (Pair)formatter.Deserialize(fileContents);
ViewState = statePair.First;
ControlState = statePair.Second;
leitor.Fechar();
stateStream.Close();
}
//
// Persiste qualquer ViewState e ControlState.
//
substituição pública void Save()
{
if (ViewState! = Nulo || ControlState! = Nulo)
{
if (Page.Session! = Nulo)
{
Fluxo stateStream = GetSecureStream();
Escritor StreamWriter = novo StreamWriter(stateStream);
Formatador IStateFormatter = this.StateFormatter;
Pair statePair = new Pair(ViewState, ControlState);
// Serializa o objeto statePair em uma string.
string serializedState = formatter.Serialize(statePair);
escritor.Write(serializedState);
escritor.Fechar();
stateStream.Close();
}
outro
throw new InvalidOperationException("Sessão necessária para StreamPageStatePersister.");
}
}
// Retorna um Stream seguro para seu ambiente.
private Stream GetSecureStream().
{
string caminho = @"d:a.txt";
FileStream fs = novo FileStream(caminho, FileMode.Open, FileAccess.ReadWrite);
retornar fs;
}
}
}
Apenas substitua a propriedade PageStatePersister:
substituição protegida PageStatePersister PageStatePersister
{
pegar
{
retornar novo StreamPageStatePersister (Página })
;
Através da breve introdução acima, devemos ter algum entendimento, mas o que precisamos entender é: no ASP.NET1.1 só podemos completar as funções acima reescrevendo age.SavePageStateToPersistenceMedium() e Page.LoadPageStateFromPersistenceMedium(); .NET1.1 No ASP.NET2.0, além disso, também o completamos escrevendo uma nova subclasse de PageStatePersister e substituindo a propriedade PageStatePersister. Claro, se você ler o conteúdo a seguir. , você entenderá que escrever uma nova subclasse de PageStatePersister é de uso real.
Usando o adaptador de página
Como o mecanismo de persistência de estado está relacionado à renderização adaptativa e à funcionalidade do lado do cliente, MyPageAdapter é fornecido para ativar o DatabasePageStatePersister do aplicativo ASP.NET. Finalmente, um arquivo de recursos do navegador (.browser) é fornecido para ativar o MyPageAdapter para uma classe específica de clientes (neste caso, o navegador da Web padrão).
Para esse conteúdo, consulte o projeto PageAdapter no código-fonte que forneci. Você entenderá depois de ler.
usando System.Security.Permissions;
usando System.Web;
o namespace
System.Web.UI;
{
[AspNetHostingPermission(SecurityAction.Demand, Nível = AspNetHostingPermissionLevel.Minimal)]
classe pública MyPageAdapter: System.Web.UI.Adapters.PageAdapter
{
substituição pública PageStatePersister GetStatePersister()
{
retornar novo PageAdapter.DatabasePageStatePersister(Página);
}
}
}
Finalmente, para habilitar o adaptador MyPageAdapter, você deve criar um diretório chamado App_Browsers no diretório raiz do aplicativo ASP.NET e incluir um arquivo .browser contendo as informações de configuração (na verdade, todas elas são adicionadas quando você o adiciona para o projeto Um arquivo .browser será preenchido automaticamente para você pelo vs2005 O elemento <refID no arquivo de configuração indica que a configuração substitui o valor especificado pelo navegador padrão no arquivo de configuração Default.browser. Este exemplo usa MyPageAdapter para ASP. Páginas da web .NET (mas geralmente
os adaptadores
não são usados).
<refID do navegador = “Padrão” >
<controlAdaptadores>
<adaptador
controlType="System.Web.UI.Página"
adaptadorType="PageAdapter.MyPageAdapter" />
</controlAdaptadores>
</navegador>
</navegadores>
Isso pode ser visto no projeto TestPageAdapter no código-fonte. Este projeto é usado para demonstrar o adaptador de página.
A conclusão
é relativamente simples e pode não ser muito clara. Quanto às vantagens e desvantagens de vários mecanismos de persistência, não os testei especificamente, e o último item “Usar adaptador de página” não é um mecanismo de persistência, mas usa um adaptador. , então não substituiremos
o atributo PageStatePersister. Parece-me que não é muito útil, porque podemos colocar a ação de substituir PageStatePersister na classe base da página, e todas as outras páginas podem herdar esta classe base. como está no meu código. É problemático usar este adaptador de página. Claro, não sei muito sobre o adaptador de página.
Além disso, uma breve explicação do meu código fonte:
1. Projeto PageAdapter
DatabasePageStatePersister.cs: uma subclasse da classe PageStatePersister MyPageAdapter.cs: adaptador de páginas de acesso ao banco de dados DataAccess.cs e ViewSate.cs, pertencente à classe auxiliar.
2. O projeto StreamPageAdapter
é semelhante ao acima, então não entrarei em detalhes
3. Projeto SaveStateToDatabase
StateInHiddenField.aspx: Teste o mecanismo de armazenamento padrão, ou seja, você pode ver muitas coisas confusas ao olhar. o arquivo de origem da página.
StateInSession.aspx: O mecanismo de armazenamento é Session.
StateInDatabase.aspx: O banco de dados do mecanismo de armazenamento é o tipo de método de reescrita. Ele pode ser usado por asp.net1.1 e 2.0.
StateInDatabase2.aspx: Escreva uma nova subclasse de PageStatePersister e substitua a propriedade PageStatePersister
StateInFile.aspx: Salve ViewState em uma pasta no servidor.
4. Projeto TestPageAdater.
Usado para testes e adaptadores.