Was verursacht diese "Ungültige Länge für ein Base-64-Zeichen-Array"?

91

Ich habe hier sehr wenig zu tun. Ich kann dies nicht lokal reproduzieren, aber wenn Benutzer den Fehler erhalten, erhalte ich eine automatische Benachrichtigung über E-Mail-Ausnahmen:

Invalid length for a Base-64 char array.

  at System.Convert.FromBase64String(String s)
  at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
  at System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Deserialize(String serializedState)
  at System.Web.UI.Util.DeserializeWithAssert(IStateFormatter formatter, String serializedState)
  at System.Web.UI.HiddenFieldPageStatePersister.Load()

Ich bin geneigt zu glauben, dass es ein Problem mit Daten gibt, die viewstate zugewiesen werden. Beispielsweise:

List<int> SelectedActionIDList = GetSelectedActionIDList();
ViewState["_SelectedActionIDList"] = SelectedActionIDList;

Es ist schwierig, die Fehlerquelle zu erraten, ohne den Fehler lokal reproduzieren zu können.

Wenn jemand Erfahrung mit diesem Fehler hat, würde ich wirklich gerne wissen, was Sie herausgefunden haben.

Schlank
quelle

Antworten:

36

Ich habe diesen Fehler gesehen, der durch die Kombination eines großen Ansichtszustands und über aggressiver Geräte / Firewalls zum Filtern von Inhalten (insbesondere im Umgang mit K-12-Bildungseinrichtungen) verursacht wurde.

Wir haben es umgangen, indem wir Viewstate in SQL Server gespeichert haben. Bevor Sie diesen Weg gehen, würde ich empfehlen, die Verwendung von viewstate einzuschränken, indem Sie nichts Großes darin speichern und es für alle Steuerelemente deaktivieren, die es nicht benötigen.

Referenzen zum Speichern von ViewState in SQL Server:
MSDN - Übersicht über PageStatePersister
ASP Alliance - Einfache Methode zum Speichern von ViewState in SQL Server
Code Project - ViewState-Anbietermodell

Jimmie R. Houts
quelle
Ich habe den Status der Seite kopiert und in Word eingefügt. Es war über 86000 Zeichen lang. Das scheint zu viel.
Slim
Huch, ich stoße jetzt auf das Problem. Ich habe ViewState für alle Steuerelemente deaktiviert, die ich möglicherweise kann. Ich verwende ein Assistentensteuerelement mit mehreren Seiten und viel Inhalt. Irgendein Rat?
Mike Cole
@ Mike C., das ist ein sehr frustierendes Problem! Sie können den Inhalt jeder Seite des Assistenten in Benutzersteuerelemente aufteilen und den Inhalt bei Bedarf laden (über Ajax?). Dies ist natürlich nur eine Lösung für diese eine Seite. Wenn Sie das Problem auf einer konsistenten Basis bemerken, sollten Sie möglicherweise den Ansichtsstatus in Ihrer Datenbank speichern. Ich habe meine Antwort mit Referenzen zum Speichern des Ansichtsstatus in SQL Server aktualisiert.
Jimmie R. Houts
1
Ein weiteres Problem, auf das ich mit mehr als 86000 Zeichen gestoßen bin (unter der Annahme von Einzelbyte-Zeichen kann es tatsächlich nahe bei 85 KB liegen), besteht darin, dass Ihre .NET-App möglicherweise auch Viewstate-Zeichenfolgen auf den Heap für große Objekte setzt, was zu Heap führen kann Fragmentierung im Laufe der Zeit (und schließlich OutOfMemoryException), wenn der App-Pool nicht recycelt wird.
nichts ist
Ich habe das gleiche Problem. Wie kann dieses Problem behoben werden? Bitte klären Sie es.
Sajith
84

Nachdem urlDecode den Text verarbeitet hat, werden alle '+' Zeichen durch '' ersetzt ... daher der Fehler. Sie sollten diese Anweisung einfach aufrufen, um Base 64 wieder kompatibel zu machen:

        sEncryptedString = sEncryptedString.Replace(' ', '+');
Jalal El-Shaer
quelle
Tolles Zeug. Vielen Dank. Ich habe einen ASP.NET-Webdienst von einer C ++ - MFC-Anwendung aus aufgerufen und hätte in viele Richtungen verzweigen können, um dies zu lösen, und nachdem ich bereits einige Stunden damit verbracht hatte. Sie haben mir gerade eine Menge Zeit gespart.
nspire
3
Treffen Sie einfach dieses Problem und wie Sie sagten, es waren Leerzeichen, die durch ein +behobenes ersetzt wurden. Held!
Mattytommo
Kann jemand eine Anleitung geben, wo dieser Code eingefügt werden soll? Ich beschäftige mich häufig mit diesem Problem, aber anhand des Code-Snippets kann ich nicht bestimmen, wo das Update implementiert werden soll.
dst3p
@ dst3p Verwenden Sie es überall dort, wo in der Verarbeitungspipeline der Fehler auftritt. Überprüfen Sie Ihre Stapelverfolgung und stellen Sie fest, welche Methode den Fehler verursacht.
Jalal El-Shaer
21

Ich vermute, dass etwas entweder zu oft codiert oder decodiert - oder dass Sie Text mit mehreren Zeilen haben.

Base64-Zeichenfolgen müssen ein Vielfaches von 4 Zeichen lang sein - alle 4 Zeichen stehen für 3 Byte Eingabedaten. Irgendwie sind die von ASP.NET zurückgegebenen Ansichtsstatusdaten beschädigt - die Länge ist kein Vielfaches von 4.

Protokollieren Sie den Benutzeragenten, wenn dies auftritt? Ich frage mich, ob es irgendwo ein schlecht benommener Browser ist ... eine andere Möglichkeit ist, dass es einen Proxy gibt, der ungezogene Dinge tut. Versuchen Sie ebenfalls, die Inhaltslänge der Anforderung zu protokollieren, damit Sie sehen können, ob dies nur bei großen Anforderungen der Fall ist.

Jon Skeet
quelle
In meinem Fall ist der Browser immer Safari, entweder mobile oder Desktop-Version
Cockypup
12

Versuche dies:

public string EncodeBase64(string data)
{
    string s = data.Trim().Replace(" ", "+");
    if (s.Length % 4 > 0)
        s = s.PadRight(s.Length + 4 - s.Length % 4, '=');
    return Encoding.UTF8.GetString(Convert.FromBase64String(s));
}
Petr Voborník
quelle
Diese Methode half bei der Behebung des Problems. Obwohl ich keine UTF8-Codierung verwendet habe
Abhishek Shrivastava
10
int len = qs.Length % 4;
            if (len > 0) qs = qs.PadRight(qs.Length + (4 - len), '=');

Wo qsist eine Base64-codierte Zeichenfolge?

Bhuvana
quelle
8

Wie bereits erwähnt, kann dies verursacht werden, wenn einige Firewalls und Proxys den Zugriff auf Seiten mit einer großen Menge an ViewState-Daten verhindern.

ASP.NET 2.0 führte den ViewState Chunking-Mechanismus ein der den ViewState in verwaltbare , sodass der ViewState problemlos den Proxy / die Firewall passieren kann.

Um diese Funktion zu aktivieren, fügen Sie einfach die folgende Zeile zu Ihrer web.config-Datei hinzu.

<pages maxPageStateFieldLength="4000">

Dies sollte nicht als Alternative zur Reduzierung Ihrer ViewState-Größe verwendet werden, kann jedoch ein wirksamer Rückschlag gegen den Fehler "Ungültige Länge für ein Base-64-Zeichenarray" sein, der sich aus aggressiven Proxys und dergleichen ergibt.

Red Taz
quelle
Kann dies irgendwelche Nebenwirkungen haben?
MonsterMMORPG
Keine, die ich jemals beobachtet habe, mehr Informationen über viewstate
Red Taz
Was ist Ihre optimale Länge? Ich habe es eingestellt 1024
MonsterMMORPG
1

Dies ist leider keine Antwort. Nachdem ich einige Zeit auf den zeitweiligen Fehler gestoßen bin und mich schließlich genug geärgert habe, um zu versuchen, ihn zu beheben, muss ich noch eine Lösung finden. Ich habe jedoch ein Rezept für die Reproduktion meines Problems festgelegt, das anderen helfen könnte.

In meinem Fall handelt es sich NUR um ein Localhost-Problem auf meinem Entwicklungscomputer, auf dem sich auch die Datenbank der App befindet. Es ist eine .NET 2.0-App, die ich mit VS2005 bearbeite. Auf dem Win7 64-Bit-Computer sind auch VS2008 und .NET 3.5 installiert.

Folgendes erzeugt den Fehler in verschiedenen Formen:

  1. Laden Sie eine neue Kopie des Formulars.
  2. Geben Sie einige Daten und / oder Postbacks mit einem der Steuerelemente des Formulars ein. Wiederholen Sie alles, was Sie möchten, solange keine nennenswerte Verzögerung auftritt und keine Fehler auftreten.
  3. Warten Sie eine Weile (vielleicht 1 oder 2 Minuten, nicht mehr als 5) und versuchen Sie es mit einem anderen Postback.

Ein oder zwei Minuten Verzögerung "Warten auf localhost" und dann "Verbindung wurde zurückgesetzt" vom Browser und global.asaxdie Anwendungsfehler-Trap-Protokolle der Anwendung:

Application_Error event: Invalid length for a Base-64 char array.
Stack Trace:
     at System.Convert.FromBase64String(String s)
     at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
     at System.Web.UI.Util.DeserializeWithAssert(IStateFormatter formatter, String serializedState)
     at System.Web.UI.HiddenFieldPageStatePersister.Load()

In diesem Fall ist es nicht die GRÖSSE des Ansichtszustands, sondern etwas, das mit dem Zwischenspeichern von Seiten und / oder Ansichtszuständen zu tun hat, das mich zu beißen scheint. Das Einstellen von <pages>Parametern enableEventValidation="false"und viewStateEncryption="Never"in Web.confighat das Verhalten nicht geändert. Auch das Setzen maxPageStateFieldLengthauf etwas Bescheidenes.

Fortboise
quelle
1

Schauen Sie sich Ihre HttpHandlers an. Ich habe in den letzten Monaten einige seltsame und völlig zufällige Fehler bemerkt, nachdem ich ein Komprimierungswerkzeug (RadCompression von Telerik) implementiert habe. Ich bemerkte Fehler wie:

  • System.Web.HttpException: Daten können nicht überprüft werden.

  • System.Web.HttpException: Der Client wurde getrennt .---> System.Web.UI.ViewStateException: Ungültiger Ansichtsstatus.

und

  • System.FormatException: Ungültige Länge für ein Base-64-Zeichenarray.

  • System.Web.HttpException: Der Client wurde getrennt. ---> System.Web.UI.ViewStateException: Ungültiger Ansichtsstatus.

Ich habe darüber in meinem Blog geschrieben.

Michael
quelle
Dein Blog ist ausgefallen. Haben Sie einen anderen Link oder können Sie die relevanten Informationen posten? thx
mga911
0

Dies liegt an einem riesigen Ansichtsstatus. In meinem Fall hatte ich Glück, da ich den Ansichtsstatus nicht verwendet habe. Ich habe gerade hinzugefügtenableviewstate="false" das Formular-Tag und der Ansichtsstatus stieg von 35.000 auf 100 Zeichen

Coderman
quelle
0

Beim ersten Testen auf Membership.ValidateUser mit einem SqlMembershipProvider verwende ich einen Hash-Algorithmus (SHA1) in Kombination mit einem Salt. Wenn ich die Salt-Länge auf eine Länge geändert habe, die nicht durch vier teilbar ist, habe ich diesen Fehler erhalten.

Ich habe keine der oben genannten Korrekturen versucht, aber wenn das Salz geändert wird, kann dies jemandem helfen, dies als Ursache für diesen bestimmten Fehler zu identifizieren.

John
quelle
0

Wie Jon Skeet sagte, muss die Zeichenfolge ein Vielfaches von 4 Bytes sein. Aber ich bekam immer noch den Fehler.

Zumindest wurde es im Debug-Modus entfernt. Setzen Sie einen Haltepunkt Convert.FromBase64String()und gehen Sie den Code durch. Wie durch ein Wunder ist der Fehler für mich verschwunden :) Er hängt wahrscheinlich mit den Ansichtszuständen und ähnlichen anderen Problemen zusammen, die andere gemeldet haben.

Hammad Khan
quelle
0

Zusätzlich zu der Lösung von @ jalchr , die mir geholfen hat, stellte ich fest, dass Sie beim Aufrufen ATL::Base64Encodevon einer C ++ - Anwendung zum Codieren des Inhalts, den Sie an einen ASP.NET-Webservice übergeben, noch etwas anderes benötigen. Zusätzlich zu

sEncryptedString = sEncryptedString.Replace(' ', '+'); 

Bei der Lösung von @ jalchr müssen Sie außerdem sicherstellen, dass Sie dasATL_BASE64_FLAG_NOPAD Flag nicht verwenden für ATL::Base64Encode:

 BOOL bEncoded = Base64Encode(lpBuffer,
                    nBufferSizeInBytes,
                    strBase64Encoded.GetBufferSetLength(base64Length),
                    &base64Length,ATL_BASE64_FLAG_NOCRLF/*|ATL_BASE64_FLAG_NOPAD*/);
nspire
quelle