これの原因「Base-64 char配列の無効な長さ」


91

ここで続けることはほとんどありません。これをローカルで再現することはできませんが、ユーザーがエラーを受け取ると、自動メール例外通知が表示されます。

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()

ビューステートに割り当てられているデータに問題があると思う傾向があります。 例えば:

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

エラーをローカルで再現することができなければ、エラーの原因を推測することは困難です。

誰かがこのエラーの経験を持っている場合、私はあなたが何を見つけたかを本当に知りたいです。

回答:


36

このエラーは、適切なサイズのビューステートと攻撃的なコンテンツフィルタリングデバイス/ファイアウォールの組み合わせ(特にK-12教育機関を扱う場合)が原因で発生します。

ViewstateをSQL Serverに格納することで、この問題を回避しました。そのルートに進む前に、ビューステートに大きなものを格納せず、それを必要としないすべてのコントロールに対してオフにすることで、ビューステートの使用を制限することをお勧めします。

SQL ServerにViewStateを格納するための参照:
MSDN-PageStatePersister
ASP Allianceの概要-SQL Server コードプロジェクトにViewState を格納する簡単な方法-ViewState
プロバイダーモデル


ページのビューステートをコピーしてWordに貼り付けました。長さが86000文字を超えていました。それは多すぎるようです。
スリム

いや、私は今問題にぶつかっています。可能なすべてのコントロールでViewStateをオフにしました。複数のページと多くのコンテンツを含むウィザードコントロールを使用しています。何かアドバイス?
マイクコール

@マイクC.、これは非常にイライラする問題です!ウィザードの各ページのコンテンツをユーザーコントロールに分割し、オンデマンドでコンテンツを読み込むことができます(ajaxを介して?)。もちろん、これはその1ページの解決策にすぎません。一貫して問題が発生し始めた場合は、データベースにビューステートを格納することを検討してください。SQL Serverにビューステートを格納するための参照で私の回答を更新しました。
ジミーR.ハウツ、

1
長い86000文字(実際には1バイト文字を想定すると85Kに近いと思われます)で遭遇したもう1つの問題は、.NETアプリがビューステート文字列を大きなオブジェクトヒープに配置し始め、ヒープにつながる可能性があることですアプリプールがリサイクルされない場合、時間の経過に伴う断片化(および最終的にはOutOfMemoryException)。
2013

同じ問題が発生しました。この問題の解決方法を明確にしてください。
Sajith、2014年

84

urlDecodeがテキストを処理した後、すべての '+'文字を '' ...に置き換えるため、エラーが発生します。このステートメントを呼び出して、base 64互換にする必要があります。

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

素晴らしいもの。ありがとう。私はC ++ MFCアプリケーションからASP.NET Webサービスを呼び出していましたが、これを解決しようとして多くの方向に分岐し、すでに十分な時間を費やしていた可能性があります。あなたは私にたくさんの時間を節約しました。
nspire

3
ちょうどこの問題にぶつかって、あなたが言ったようにそれはスペースだったので、+それを修正したものに置き換えます。ヒーロー!
mattytommo 2013

このコードをどこに含めるかについて誰かがガイダンスを与えることはできますか?私は頻繁にこの問題を扱っていますが、コードスニペットからは、修正を実装する場所を決定できません。
dst3p

@ dst3p処理パイプラインのどこでエラーが発生しても、それを使用します。スタックトレースを確認して、エラーの原因となっているメソッドを確認します。
Jalal El-Shaer

21

私の推測では、何かが頻繁にエンコードまたはデコードされているか、または複数行のテキストが含まれています。

Base64文字列は、長さが4文字の倍数である必要があります。4文字ごとに3バイトの入力データを表します。どういうわけか、ASP.NETによって返されるビューステートデータが破損しています-長さが4の倍数ではありません。

これが発生した場合、ユーザーエージェントをログに記録しますか?それがどこかに問題のあるブラウザなのかどうか疑問に思います...別の可能性は、いたずらなことをしているプロキシがあることです。同様に、リクエストのコンテンツの長さをログに記録して、大きなリクエストでのみ発生するかどうかを確認します。


私の場合、ブラウザは、モバイルまたはデスクトップバージョンのいずれか、常にサファリです
cockypup

12

これを試して:

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

この方法は問題の解決に役立ちました。私はUTF8エンコーディングを使用していませんでした
Abhishek Shrivastava

10
int len = qs.Length % 4;
            if (len > 0) qs = qs.PadRight(qs.Length + (4 - len), '=');

どこqs任意のbase64でエンコードされた文字列であります


8

他の人が述べたように、これは一部のファイアウォールとプロキシが大量のViewStateデータを含むページへのアクセスを妨げている場合に発生する可能性があります。

ASP.NET 2.0はViewState Chunkingメカニズムを導入しましたを管理可能なチャンクに分割が問題なくプロキシ/ファイアウォールを通過できるようになりました。

この機能を有効にするには、web.configファイルに次の行を追加します。

<pages maxPageStateFieldLength="4000">

これはViewStateサイズを小さくする代わりに使用すべきではありませんが、積極的なプロキシなどが原因で発生する「Base-64 char配列の無効な長さ」エラーに対する効果的なバックストップになる可能性があります。


これには副作用がありますか?
MonsterMMORPG 2016年

私が今まで観察したものはありません。ビューステートの詳細
Red Taz

それであなたの最適な長さは何ですか?私はそれを1024に設定しました
MonsterMMORPG

1

残念ながら、これは答えではありません。しばらくの間欠的なエラーに遭遇し、最終的にそれを修正しようとするのに十分な迷惑になった後、私はまだ修正を見つけることができません。しかし、私は他の人を助けるかもしれない私の問題を再現するためのレシピを決めました。

私の場合は、アプリのDBもある開発マシンでのローカルホストの問題だけです。VS2005で編集している.NET 2.0アプリです。Win7 64ビットマシンには、VS2008と.NET 3.5もインストールされています。

さまざまな形式からエラーを生成するものは次のとおりです。

  1. フォームの新しいコピーを読み込みます。
  2. データを入力するか、フォームのコントロールを使用してポストバックします。大きな遅延がない限り、好きなだけ繰り返してください。エラーは発生しません。
  3. しばらく待ってから(1〜2分、多分5以下)、別のポストバックを試してください。

1〜2分遅延して、「localhostを待機」してから「接続がリセットされました」と、ブラウザglobal.asaxのアプリケーションエラートラップログ:

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()

この場合、それはビューステートのサイズではありませんが、ページやビューステートのキャッシュと関係があり、私を苦しめているようです。設定<pages>パラメータをenableEventValidation="false"、とviewStateEncryption="Never"Web.config動作を変更しませんでした。どちらもmaxPageStateFieldLength適度なものに設定しませんでした。


1

HttpHandlersを見てください。圧縮ツール(TelerikのRadCompression)を実装した後、過去数か月にわたっていくつかの奇妙で完全にランダムなエラーに気づきました。私は次のようなエラーに気づいていました:

  • System.Web.HttpException:データを検証できません。

  • System.Web.HttpException:クライアントが切断されました。---> System.Web.UI.ViewStateException:無効なビューステート。

そして

  • System.FormatException:Base-64文字配列の長さが無効です。

  • System.Web.HttpException:クライアントが切断されました。---> System.Web.UI.ViewStateException:無効なビューステート。

私はこれについて書いた私のブログに。


ブログがダウンしています。別のリンクがありますか、または関連情報を投稿できますか?thx
mga911 2014年


0

これはビューステートが大きいためです。私の場合、ビューステートを使用していなかったので幸運でした。enableviewstate="false"formタグを追加したところ、ビューステートが35kから100文字になりました


0

SqlMembershipProviderを使用したMembership.ValidateUserの初期テスト中に、ソルトと組み合わせたハッシュ(SHA1)アルゴリズムを使用しました。ソルトの長さを4で割り切れない長さに変更すると、このエラーが発生しました。

私は上記の修正のいずれも試していませんが、ソルトが変更されている場合、これはこのエラーの原因として誰かがそれを特定するのに役立つ可能性があります。


0

Jon Skeetが言ったように、文字列は4バイトの倍数でなければなりません。しかし、まだエラーが発生していました。

少なくともデバッグモードでは削除されました。ブレークポイントをオンConvert.FromBase64String()にして、コードをステップ実行します。奇妙なことに、エラーは私にとっては消えました:)これはおそらく他の人が報告したように、ビューステートや他の同様の問題に関連しています。


0

私を助ける@jalchrのソリューションに加えてATL::Base64Encode、C ++アプリケーションから呼び出してASP.NET Webサービスに渡すコンテンツをエンコードする場合、他にも何かが必要であることがわかりました。に加えて

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

@ jalchrのソリューション、あなたはまた、あなたがいることを確認する必要があります使用しないATL_BASE64_FLAG_NOPADで旗をATL::Base64Encode

 BOOL bEncoded = Base64Encode(lpBuffer,
                    nBufferSizeInBytes,
                    strBase64Encoded.GetBufferSetLength(base64Length),
                    &base64Length,ATL_BASE64_FLAG_NOCRLF/*|ATL_BASE64_FLAG_NOPAD*/);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.