Problembehandlung beim Fehler "Ansicht" ist ungültig, wenn ASP.NET

In diesem Artikel werden Techniken zum Debuggen und beheben von Problemen mit dem Ansichtsstatus in Microsoft ASP.NET Anwendungen vorgestellt.

Ursprüngliche Produktversion:   ASP.NET
Ursprüngliche KB-Nummer:   829743

Einführung

View stateist ein Feature in ASP.NET, das es Seiten ermöglicht, den Status automatisch beizubehalten, ohne sich auf den Serverzustand zu verlassen (z. B. Sitzungsstatus). Probleme im Zusammenhang mit dem Ansichtsstatus können jedoch schwierig zu debuggen sein. Wenn Probleme mit dem Ansichtsstatus auftreten, wird in den meisten Fällen die folgende Fehlermeldung im Webbrowser angezeigt, die wenig Darauf hinweist, was das Problem verursachen könnte:

Der Ansichtszustand ist für diese Seite ungültig und möglicherweise beschädigt.

In diesem Artikel werden einige Techniken beschrieben, die zum Debuggen und Beheben von Problemen mit dem Ansichtsstatus verwendet werden können.

Stellen Sie sicher, dass keine Probleme auftreten, die behoben wurden.

Eine Reihe von Problemen mit dem Ansichtsstatus wurden mit ASP.NET 1.0-Hotfixes und Service Packs behoben, und diese Fixes sind auch Teil von ASP.NET 1.1. Stellen Sie sicher, dass Sie die neuesten Korrekturen angewendet haben, bevor Sie Probleme nachverfolgen, die bereits behoben wurden. Die neuesten Updates für Microsoft .NET Framework finden Sie hier: Herunterladen .NET Framework.

Festlegen des validationKey-Attributs, wenn Sie in einer Webfarm ausgeführt werden

In einer Webfarm kann jede Clientanforderung auf jedem Postback zu einem anderen Computer wechseln. Aufgrund dieses Verhaltens können Sie das Attribut nicht validationKey auf AutoGenerate in der datei Machine.config festlegen. Stattdessen müssen Sie den Wert des validationKey Attributs auf eine feste Zeichenfolge festlegen, die von allen Computern in der Webfarm freigegeben wird.

Weitere Informationen zu diesem Problem finden Sie unter Troubleshooting Invalid viewstate issues.

Dynamisch generierte Typen nicht im Ansichtsstatus in einer Webfarm speichern

Wenn ASP.NET Dateien dynamisch kompiliert, werden die Dateien in Assemblys mit zufälligen Namen integriert (z. B. kann ein Dateiname jp395dun.dll sein). Wenn Sie eine Webfarm ausführen, werden dieselben Dateien in Assemblys mit unterschiedlichen zufälligen Namen kompiliert. Normalerweise ist dies kein Problem, da niemand von diesen Assemblynamen ausgeht. Wenn Sie jedoch einen dynamisch kompilierten Typ mithilfe der binären Serialisierung in den Ansichtszustand versetzen, wird der Name der Assembly als Teil der Ansichtsstatusdaten eingeschlossen. Wenn dieser Ansichtsstatus später an einen anderen Server in der Webfarm gesendet wird, kann der Ansichtsstatus nicht deserialisiert werden, da er unterschiedliche Assemblynamen verwendet.

Die beste Lösung für dieses Problem besteht darin, die Verwendung der binären Serialisierung zu vermeiden. Die binäre Serialisierung verwendet viele Ressourcen, auch wenn dieses Problem nicht auftritt. Beschränken Sie stattdessen den Ansichtszustand auf eine Kombination aus Arrays, Paaren, Triplets und einfachen Typen (z. B. Zeichenfolgen, Int und andere Typen). System.Web.UI.Pair und System.Web.UI.Triplet einfache Wrappertypen sind, die das Ansichtsstatusmodul effizient verarbeiten kann.

Eine alternative Lösung, um dieses Problem zu vermeiden, besteht darin, die Typen, die Sie im Ansichtsstatus speichern, in eine vorkompilierte Assembly zu verschieben, entweder im Ordner "Bin" oder im Global Assembly Cache. Mit diesem Fix wird die Leistung nicht behoben, es wird jedoch sichergestellt, dass die Assembly auf allen Computern denselben Namen aufweist.

Hinweis

Wenn Sie komplexe Datentypen im Ansichtsstatus speichern und dieses Problem feststellen, enthalten die Aufrufstapelinformationen Stapel, die den folgenden ähneln:

[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

Der Zweck der Mac-Funktion (Computerauthentifizierungscode) für den Ansichtsstatus besteht darin, Clients das Senden einer Anforderung, die einen schädlichen Ansichtsstatus enthält, unmöglich zu machen. Dieses Feature ist standardmäßig im folgenden Flag in der Machine.config-Datei aktiviert.

enableViewStateMac="true"

Die einfachste Möglichkeit, festzustellen, ob das Problem, mit dem Sie es zu tun haben, mit dem MAC-Feature zusammenhängt, besteht darin, das Feature zu deaktivieren. Ändern Sie dazu das Kennzeichen in der Machine.config-Datei in den folgenden Code.

enableViewStateMac="false"

Wenn Sie keine Anzeigestatusfehler mehr erhalten, liegt das Problem im Zusammenhang mit dem MAC-Feature.

Wichtig

Deaktivieren Sie nur die MAC-Funktion für den Ansichtsstatus, um das Problem zu diagnostizieren. Sie sollten den Ansichtsstatus MAC nicht deaktiviert lassen, um das Problem zu umgehen. Wenn ja, könnten Sie Sicherheitsrisiken einführen. Weitere Informationen finden Sie unter Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication.

Wenn Sie die MAC-Funktion für den Ansichtsstatus deaktivieren und dann den Ansichtsstatus für Steuerelemente verwenden, die keine HTML-Codierung ausführen (z. B. ein Bezeichnungssteuerelement), können Angreifer die Ansichtsstatusdaten manipulieren und beliebige Daten in den Ansichtszustand versetzen. Diese zufälligen Daten werden decodiert und dann von Steuerelementen verwendet, wenn sie die bereitgestellte Seite rendern. Daher können Angreifer Skripts in die Anwendung einfügen, es sei denn, Sie arbeiten daran, den Angriff zu verhindern. Beispielsweise könnte ein Angreifer die Daten decodieren, Skripts in die Daten einfügen, in denen sich ein Bezeichnungssteuerelement befindet, und dann von einer Website darauf verweisen. Jeder, der auf den Link klickt, wäre das Opfer eines Skripteinschleusungsangriffs, der möglicherweise seine Authentifizierungscookies oder Sitzungs-ID stehlen könnte. Das Skript könnte es einem Angreifer auch ermöglichen, Statusdaten für Steuerelemente zu ändern, die den Ansichtsstatus verwenden, und anwendungsspezifische Angriffe können als Ergebnis auftreten.

Im Allgemeinen empfiehlt Microsoft, das MAC-Feature für den Ansichtsstatus nicht zu deaktivieren, es sei denn, Sie sind sicher, dass Sie entweder den Ansichtsstatus für alle Steuerelemente deaktiviert haben, die ihre Ausgabe nicht im HTML-Code codieren (z. B. DataGrid-Steuerelemente, DataList-Steuerelemente, Bezeichnungssteuerelemente und andere Steuerelemente), oder dass Sie ihre Werte für jede Anforderung immer explizit auf etwas festlegen, das als sicher bekannt ist.

Ermitteln Sie genau, welche Ausnahme auftritt, wenn Sie die Fehlermeldung erhalten

Leider ist die Fehlermeldung zu ungültigen Ansichtszuständen, die im Abschnitt "Einführung" dieses Artikels erwähnt wird, nicht informativ. Die Fehlermeldung wird durch eine Ausnahme ausgelöst, die ausgelöst wird, wenn der Ansichtsstatus verarbeitet wird. Das Problem besteht darin, dass die Ausnahme genutzt wird und die Details in der Fehlermeldung verloren gehen.

Mithilfe eines Debuggers können Sie die ursprüngliche Ausnahme ermitteln. Hierzu müssen Sie einen Debugger an den ASP.NET Prozess anfügen (Aspnet_wp.exe oder W3wp.exe), und dann festlegen, dass alle Ausnahmen erfasst werden. Der Debugger stoppt wahrscheinlich bei einigen Ausnahmen, die nicht relevant sind, aber schließlich wird er die Ausnahme für den Ansichtsstatus treffen und nützliche Informationen für die Problembehandlung bereitstellen.

Die folgenden Schritte sind ein Beispiel, das den Runtime-Debugger (Cordbg.exe) verwendet.

  1. Führen Sie an einer Eingabeaufforderung den Befehl aus, iisreset um sicherzustellen, dass Sie über einen guten Ausgangspunkt verfügen, und navigieren Sie dann zu einer Seite auf Ihrer Website.

  2. Führen Sie an einer Eingabeaufforderung cordbg.exe .

  3. Geben Sie an der Eingabeaufforderung pro ein, und drücken Sie dann die EINGABETASTE. Eine Liste der verwalteten Prozesse wird angezeigt. Es sollte entweder der Aspnet_wp.exe Prozess oder der W3wp.exe Prozess angezeigt werden. Notieren Sie sich die PID.

  4. Geben Sie an der Eingabeaufforderung eine PID ein, die an den Prozess angefügt werden soll.

    Hinweis

    Ersetzen Sie pid durch die PID, die in Schritt 3 notiert wurde.

  5. Geben Sie an der Eingabeaufforderung ca e ein, um Cordbg.exe anzufordern, alle Ausnahmen zu unterbrechen, und geben Sie dann Gto ein, um den Prozess auszuführen.

  6. Wenn Sie eine Ausnahme erhalten, geben Sie w ein, um den Stapel anzuzeigen. Wenn der Stapel eine Ansichtsstatusausnahme ist (suchen Sie im LoadPageStateFromPersistenceMedium Stapel nach), kopieren Sie alle Ausnahme- und Stapelinformationen aus dem Befehlsfenster, und speichern Sie die Informationen. Diese Informationen können Ihnen helfen, das Problem zu verstehen. Wenn die Ausnahme keinen Bezug hat, geben Sie g ein.

Versuchen Sie, den Ansichtsstatus in der Sitzung zu speichern.

Standardmäßig wird der Ansichtsstatus mithilfe eines <input type=hidden> Felds, das an den Browser gesendet wird, gerundet. Der Browser sendet das Feld dann bei der nächsten Anforderung zurück an den Server. In einigen Fällen kann dieser Ansichtszustand groß werden und eine potenzielle Ursache für Probleme sein. Einige Browser können ein so großes ausgeblendetes Feld (und die resultierende große Anforderung) nicht verarbeiten, und die Browser können den Ansichtsstatus abschneiden. Wenn Sie den Ansichtsstatus abschneiden, wird eine Fehlermeldung angezeigt, bei der der Ansichtsstatus beschädigt ist. Dieses Verhalten tritt höchstwahrscheinlich in einfacheren Browsern auf. Dieses Verhalten kann beispielsweise in einem Browser auf einem PDA auftreten.

Um festzustellen, ob möglicherweise ein solches Problem auftritt, versuchen Sie, den Ansichtsstatus in der Sitzung zu speichern. Im folgenden Beispiel wird die Vorgehensweise veranschaulicht.

<%@ 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> 

Die folgende Codezeile ist nur in ASP.NET 1.0 erforderlich, um einen Fehler zu umgehen. In ASP.NET 1.1 ist dies nicht erforderlich.

<input type=hidden name=__VIEWSTATE>

Bestimmen, ob das Problem durch die Wiederverwendung von Arbeitsprozess verursacht wird

Stellen Sie sich folgendes Szenario vor:

  • Sie führen ASP.NET unter Microsoft-Internetinformationsdienste (IIS) 6.0 aus.
  • Der Anwendungspool wird unter einer anderen Identität als dem lokalen Systemkonto, dem Netzwerkdienstkonto oder einem Konto auf Administratorebene ausgeführt.
  • Das validationKey-Attribut des <machineKey> Elements wird in der Konfigurationsdatei auf "AutoGenerate" festgelegt.

In diesem Szenario tritt durch das folgende Verfahren ein Ansichtsstatusfehler auf:

  1. Ein Benutzer durchsucht eine Seite.
  2. Der Arbeitsprozess, der die ASP.NET Anwendung wiederverwendet.
  3. Der Benutzer sendet die Seite zurück.

Die Problemumgehung für dieses Szenario besteht darin, ein explizites validationKey-Attribut in der Konfigurationsdatei zu verwenden.

References