web-dev-qa-db-ja.com

ときどき無効なビューステートエラーを無視する必要がありますか?

時々(毎日1回程度)ASP.NET 3.5アプリケーションのログに次のタイプのエラーが表示されます

  • 無効なビューステート
  • 無効なポストバックまたはコールバック引数

これらは、ASP.NETアプリケーションで時々「発生する」ものですか。問題の原因を診断するために多くの時間を費やすことをお勧めしますか?

56
Richard Everett

まあそれは依存します。無効なビューステートはさまざまな理由で発生します。

  1. ビューステートが大きすぎて、ユーザーがページにポストバックを引き起こす前にレンダリングが完了していません。修正は通常、ポストバックをトリガーするすべてのコントロールを無効にし、ページの読み込みが完了したらクライアント側で有効にすることです-参照 http://blogs.msdn.com/tom/archive/2008/03/14/validation- of-viewstate-mac-failed-error.aspx
  2. ビューステートMACを使用していますが(セキュリティ上の理由から使用する必要があります)、マシンキーを設定しておらず、アプリケーションプールがリサイクルして新しいキーを生成しています。 ViewStateUserKeyを設定することを忘れないでください。
  3. 誰かが古いバージョンのIEを使用しているため、非表示のフォームフィールドが切り捨てられます。この場合、viewstateをページから session state に移動する必要があります=。
  4. Viewstate MACの問題は、通常、ユーザーがWebファームにいて、web.configでマシンキーを設定するのを忘れていることを示します。ただし、これを行った場合は、おそらく悪いことをしようとしている人(コメントを投稿するボット、無効にされたコントロールのイベントをトリガーしようとしている人など)である可能性があります。

何をするにしてもしないビューステートまたはイベントの検証をオフにします。

49
blowdart

1つの問題は、ユーザーのルーターがフォームフィールドを切り捨てることにあります。これを回避するには、web.configでMaxPageStateFieldLengthを小さめの数値(100など)に設定し、ViewStateを小さなチャンクに分割します。実行するのは非常に簡単で、 この記事 で完全に説明されています。

7
Tim Almond

例外は時々「起こる」だけではありません。それらは常に正当な理由で発生し、そのいくつかはすでに他の回答にリストされています。

ただし、ViewStateの問題を軽減するには、ViewStateを完全に無効にすることを検討してください。 ASP.NET開発者として、私たちは多くの場合、ViewStateがデフォルトであるため必要のないあらゆる場所でViewStateを使用する傾向があります。通常、コントロールの使用を検討する前に、静的HTMLの使用について考えます。コントロールを使用する場合は、ViewStateを有効にする必要があるかどうかを検討してください。多くの場合、これを無効にするとページの読み込み時間が短縮されるため、可能であれば実行してください。

デフォルトでは無効になっているので、人々はこのように考えざるを得ませんでしたが、そうではありません。

コメントに回答するための更新:

私の頭の中で、ViewStateをオフにする3つの機会を思いつきました。

  1. すべてのポストバックでデータが読み込まれる場合は、ViewStateを無効にします。 AJAX有効なサイト(つまりrealAJAXは、そのUpdatePanelの種類ではありません;))。通常、最初のロードでデータをロードし、次にAJAXリクエストを使用してデータをリロード/更新します。場合によっては、すべてのViewStateを無効にする目的でのみアクセスし、代わりにデータをサーバーにキャッシュします。

  2. 本当に静的なコンテンツにデータバインドする場合は、ViewStateを無効にすることも検討できます。ときどき、データベースなどの小さな静的basedataテーブルにデータバインドされているリストを見つけます。これは危険な場合がありますが、データが変更されないと確信している場合は、データを静的コンテンツとしてページに移動する可能性があります(データを別のコントロールにラップして、データの静的コピーが複数ないようにすることができます) )。ただし、データが変更された場合は、手動で変更する必要があります。

  3. ラベルなどの単純なコントロールは、多くの場合、ViewStateを無効にするのに適した候補です。

最後に、ASP.NET MVCフレームワークに切り替えて、これらの問題に永遠に別れを告げることができます。これは、他の問題が発生した場合でも実行する予定です。 ;)

4
JohannesH

BlowDartは、無効なビューステート問題に対する正しい答えを持っています。おそらく、アプリプールがリサイクルされて暗号化キーが変更されているためです。

サポートについては、以下の投稿を参照してください。

。NETアプリケーションでの不安定な無効なビューステートの問題

ASP .Net Membership を使用してユーザーログインを永続的にする

4
Tom Halladay

無効なビューステートには、ロガー、ユーザー、またはWebサイトの値はありません。エンドユーザーには、これらのエラーは表示されません。このエラーを回避するには、次のInGlobal.ascxを追加してください。

void Application_Error(object sender, EventArgs e)
    {          
                if (ex is HttpException && ex.InnerException is ViewStateException)
                {
                    Response.Redirect(Request.Url.AbsoluteUri);
                    return;
                }
    }

詳細については、次のリンクを確認してください:

https://www.karpach.com/viewstateexception-invalid-viewstate.htm

2
Mike Darwish

この種の例外がログにスローされ、ここにリストされている他のものとは非常に異なる原因がありました。問題の一部である非常に大きなViewStateがありました。しかし、それはこれらの例外を引き起こす別の問題と組み合わされていました(そしておそらくIISからの時折の悪い応答)。

私が取り組んでいるコードベースには、ダブルクリックを回避するための素晴らしいコードがあり、その一部として、すべてのボタンのクリックイベントのJavaScriptにいくつかの要素を追加して、最初のクリック後にボタンを無効にし、通常のポストバックを行います。しかし、そのようなポストバックの呼び出しには問題がありました。私のボタンの一部には、すでに.NETによって自動的にポストバックの呼び出しが生成されていたからです。そのため、二重ポストバックが発生し、そのうちの1つに無効なViewStateがありました。余分なポストバックを削除すると、例外がなくなりました。

ViewStateのサイズを大幅に削減する必要があることはわかっていますが、これは大きなレガシーコードベースであり、そのような変更は非常に侵襲的です。

1
user12861

前者についてできることはあまりありません-私はそのような例外をトラップし、ユーザーをエラーページにバウンスし、「表示していたページの有効期限が切れています。これは通常、ユーザーがすでにデータを入力していました。」

後者はUpdatePanelsを使用するかなり大きなページで最も多く見られます。ページの読み込みが完了する前にユーザーがポストバック(またはコールバック)したときだと思います。そのため、ページの最後でタグ付けされたすべてのJavaScriptがまだ実行されていません。

繰り返しますが、エラーページに適切なメッセージを表示することを除いて、それらについてできることは多くありません。

1
teedyay

このエラーを無視することはおそらくお勧めできません。上記のすべての回答に加えて、ビューステートの大きさを調べることを検討してください。大きなビューステートは、プロキシサーバーによって切り捨てられる可能性があります。

ビューステートが大きい場合は、ASP.netトレースを使用して、ビューコントロールを使用しているコントロールと、これをオフにできる場所を確認することをお勧めします。

0
Miyagi Coder

this ブログ投稿のウェインウォルターベリーによると、別の犯人は、ページにXHTML準拠のマークアップがなくてもIE8でXHTML doctypeを使用できます。これにより、IE8はスクランブルされたパラメーターをscriptresource.axdに送信し、無効なビューステート例外をスローする可能性があります。

彼は、すべてのjavascriptブロックが// <![CDATA[]]>でラップされていることを確認するか、単にdoctypeを変更することをお勧めします(これにより、ページで他のCSS /スタイルの問題が発生する可能性があります)。

0
Element