Risoluzione dei problemi di visualizzazione non validi

di Apurva Joshi

Strumenti usati in questo strumento di risoluzione dei problemi:

  • N/D

Questo materiale viene fornito solo a scopo informativo. Microsoft non riconosce alcuna garanzia, espressa o implicita.

Panoramica

Lo stato di visualizzazione è una funzionalità in ASP.NET che consente alle pagine di mantenere automaticamente lo stato senza basarsi sullo stato del server ,ad esempio lo stato della sessione. Tuttavia, i problemi relativi allo stato di visualizzazione possono essere difficili da eseguire nel debug. Nella maggior parte dei casi, quando si verificano problemi con lo stato di visualizzazione, viene visualizzato il seguente messaggio di errore nel Web browser, con un'indicazione piccola di ciò che potrebbe causare il problema:

"The viewstate is invalid for this page and might be corrupted"

Questo articolo descrive alcune tecniche che possono essere usate per il debug e per risolvere i problemi relativi allo stato di visualizzazione.

Scenari e risoluzione dei problemi

Verificare che non si verifichino problemi risolti

Sono stati risolti diversi problemi di stato di visualizzazione con ASP.NET 1.0 hotfix e Service Pack e tali correzioni fanno parte anche di ASP.NET 1.1. Assicurarsi di aver applicato le correzioni più recenti prima di tenere traccia dei problemi già risolti. È possibile ottenere gli aggiornamenti più recenti di Microsoft .NET Framework dal sito Web MSDN (Microsoft Developer Network) seguente:

https://msdn.microsoft.com/netframework/aa569276.aspx

Impostare l'attributo validationKey se si esegue in una Web farm

In una Web farm ogni richiesta client può passare a un computer diverso in ogni postback. A causa di questo comportamento, non è possibile lasciare l'attributo validationKey impostato su AutoGenerate nel file Machine.config. È invece necessario impostare il valore dell'attributo validationKey su una stringa fissa condivisa da tutti i computer nella Web farm.

Per altre informazioni su questo problema, fare clic sul numero di articolo seguente per visualizzare l'articolo in Microsoft Knowledge Base:

https://support.microsoft.com/kb/323744

Non archiviare tipi generati in modo dinamico nello stato di visualizzazione in una Web farm

Quando ASP.NET compila i file in modo dinamico, i file vengono incorporati in assembly con nomi essenzialmente casuali, ad esempio un nome file potrebbe essere jp395dun.dll. Se si esegue una Web farm, gli stessi file verranno compilati in assembly con nomi casuali diversi. Normalmente, questo non è un problema perché nessuno fa ipotesi su tali nomi di assembly. Se tuttavia si inserisce un tipo compilato in modo dinamico nello stato di visualizzazione usando la serializzazione binaria, il nome dell'assembly verrà incluso come parte dei dati dello stato di visualizzazione. Quando tale stato di visualizzazione viene inviato successivamente a un server diverso nella Web farm, lo stato di visualizzazione non può essere deserializzato perché usa nomi di assembly diversi.

La soluzione migliore per questo problema consiste nell'evitare di usare la serializzazione binaria. La serializzazione binaria usa molte risorse anche quando non si verifica questo problema. Limitare invece lo stato di visualizzazione a una combinazione di matrici, coppie, triplette e tipi semplici, ad esempio stringhe, int e altri tipi. System.Web.UI.Pair e System.Web.UI.Triplet sono tipi di wrapper semplici che il motore dello stato di visualizzazione può elaborare in modo efficiente.

Una correzione alternativa per evitare questo problema consiste nello spostare i tipi archiviati nello stato di visualizzazione in un assembly precompilato, nella cartella Bin o nella Global Assembly Cache. Questa correzione non risolve le prestazioni, ma garantisce che l'assembly abbia lo stesso nome in tutti i computer.

Nota Se si archiviano tipi di dati complessi nello stato di visualizzazione e si verificano questo problema, le informazioni sullo stack di chiamate conterranno stack simili ai seguenti:

[FileNotFoundException: Could not load file or assembly 'App_Web_fx--sar9, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.]
 System.RuntimeTypeHandle._GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, Boolean loadTypeFromPartialName) +0
System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) +72
System.RuntimeType.PrivateGetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) +58
System.Type.GetType(String typeName, Boolean throwOnError) +57
System.Web.UI.ObjectStateFormatter.DeserializeType(SerializerBinaryReader reader) +192 
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +943 
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +384 
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +198 
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +210 
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +198 
System.Web.UI.ObjectStateFormatter.Deserialize(Stream inputStream) +142

Determinare se il problema è correlato alla funzionalità MAC dello stato di visualizzazione

Lo scopo della funzionalità codice di autenticazione del computer di visualizzazione (MAC) è rendere impossibile per i client inviare una richiesta che contiene uno stato di visualizzazione dannoso. Per impostazione predefinita, questa funzionalità è abilitata nel flag seguente nel file Machine.config.

enableViewStateMac="true"

Il modo più semplice per determinare se il problema da gestire è correlato alla funzionalità MAC consiste nel disattivare la funzionalità. A tale scopo, modificare il flag nel file Machine.config nel codice seguente.

enableViewStateMac="false"

Se non si ottengono più errori di stato di visualizzazione, il problema è correlato alla funzionalità MAC.

Importante

Disattivare solo la funzionalità MAC dello stato di visualizzazione per diagnosticare il problema. Non è consigliabile mantenere disattivato lo stato di visualizzazione MAC per risolvere il problema. In tal caso, è possibile introdurre fori di sicurezza

In generale, Microsoft consiglia di non disattivare la funzionalità MAC dello stato di visualizzazione, a meno che non sia completamente sicuro che sia stato disabilitato lo stato di visualizzazione per tutti i controlli che non codificano HTML (ad esempio, controlli DataGrid, controlli DataList, controlli Etichetta e altri controlli) o che si impostano sempre in modo esplicito i valori su ogni richiesta a un elemento noto per essere sicuro.

Determinare esattamente quale eccezione si verifica quando viene visualizzato il messaggio di errore

Sfortunatamente, il messaggio di errore di stato di visualizzazione non valido menzionato nella sezione "Panoramica" di questo articolo non è molto informativo. Il messaggio di errore viene in genere causato da un'eccezione generata quando viene elaborato lo stato di visualizzazione. Il problema è che l'eccezione viene usata e i relativi dettagli vengono persi nel messaggio di errore.

Usando un debugger, è possibile determinare l'eccezione originale. A tale scopo, è necessario collegare un debugger al processo di ASP.NET (Aspnet_wp.exe o W3wp.exe) e quindi impostarlo per rilevare tutte le eccezioni. È anche possibile configurare lo strumento Debug Diagnostics 1.2 per acquisire eccezioni gestite.

Provare a archiviare lo stato di visualizzazione nella sessione

Per impostazione predefinita, lo stato di visualizzazione viene arrotondato tramite un <campo INPUT type=hidden> inviato al browser. Il browser invia quindi il campo al server nella richiesta successiva. In alcuni casi, questo stato di visualizzazione può essere abbastanza grande e può essere una potenziale fonte di problemi. Alcuni browser non possono gestire un campo nascosto di grandi dimensioni (e la richiesta di grandi dimensioni risultante) e i browser possono troncare lo stato di visualizzazione. Troncare lo stato di visualizzazione causa un messaggio di errore "stato di visualizzazione danneggiato". Questo comportamento è più probabile che si verifichi nei browser più semplici. Ad esempio, questo comportamento può verificarsi in un browser in un PDA.

Per determinare se è possibile che si verifichi un problema di questo tipo, provare a archiviare lo stato di visualizzazione nella sessione. Nell'esempio riportato di seguito viene illustrato come procedere.

<%@ language=c# debug=true %> 
<script runat=server> 
protected override object LoadPageStateFromPersistenceMedium() 
{ 
     return Session["_ViewState"]; 
}
 
protected override void SavePageStateToPersistenceMedium(object viewState) 
{ 
     Session["_ViewState"] = viewState; 
}
 
void TextChanged(object o, EventArgs e) 
{ 
     Response.Write("TextChanged"); 
} 
</script> 
<form runat=server> 
<asp:button text=Test runat=server/> 
<asp:textbox ontextchanged=TextChanged runat=server/> 
<input type=hidden name=__VIEWSTATE> 
</form>

La riga di codice seguente è necessaria solo in ASP.NET 1.0, per risolvere un bug. In ASP.NET 1.1 più, non è necessario.

<input type=hidden name=__VIEWSTATE>

Determinare se il problema è causato dal riciclo del processo di lavoro

Si consideri lo scenario seguente.

  • Si esegue ASP.NET in Microsoft Internet Information Services (IIS) 6.0.
  • Il pool di applicazioni è in esecuzione in un'identità diversa dall'account del sistema locale, dall'account del servizio di rete o da un account a livello amministrativo.
  • L'attributo validationKey dell'elemento <MACHINEKEY> è impostato su AutoGenerate nel file di configurazione.

In questo scenario, la procedura seguente causerà un errore di stato di visualizzazione:

  1. Un utente sfoglia una pagina.
  2. Processo di lavoro che ospita l'applicazione ASP.NET ricicla.
  3. L'utente pubblica la pagina.

La soluzione alternativa per questo scenario consiste nell'usare un attributo validationKey esplicito nel file di configurazione.

Risorse aggiuntive