さらに読む前に、次の前提条件を除外してください。
- Web ファームを使用していません。
- 「DataKeyNames」を利用する GridView、DetailsView、FormView などの組み込みのデータ バインド コントロールを使用すると表示されます。
- なんらかの理由で読み込みが遅い大きなページがある場合に表示されます。
次の前提条件が true で、ポストバッキング コントロール/リンクをクリックし、ページがクライアント ブラウザーに完全にロードされていない場合、「ViewState MAC の検証に失敗しました」という例外が発生する可能性があります。
これが発生した場合、ページ プロパティ "EnableViewStateMac" を falseに設定しようとしても、問題は解決されず、同じナビゲーション動作でエラー メッセージが変更されるだけです。
このページの状態情報は無効であり、破損している可能性があります。
この例外が発生するのは、DataKeyNames を使用するコントロールでは Viewstate を暗号化する必要があるためです。Viewstate が暗号化されている場合 (デフォルト モードの Auto では、コントロールが必要な場合は暗号化しますが、それ以外の場合は必要ありません)、Page は <form> タグを閉じる直前にフィールドを追加します。ただし、この非表示フィールドは、実行時間の長いページでブラウザーにレンダリングされていない可能性があり、それより前にポストバックを行うと、ブラウザーはこのフィールドなしでポストバックを開始します (フォーム ポスト コレクション)。最終結果は、このフィールドがポストバックで省略されている場合、ページは Viewstate が暗号化されていることを認識せず、前述の例外が発生することです。IE ページは、ポストバックを行う前に完全に読み込まれることを想定しています。
ちなみに、__EVENTVALIDATION フィールドもフォームの最後にレンダリングされるため、同様の問題はイベント検証にもあります。これは、なりすましポストバックを防ぐために、サーバーによって許可および作成されたイベントからのみポストバック アクションが行われるようにするセキュリティ機能です。この機能は、レンダリング時にコントロールが有効なイベントを登録することによって実装されます (実際の Render() メソッドの間など)。最終結果は、レンダリングされた <form> タグの下部に、次のようなものが表示されます。ポストバックが発生すると、ASP.NET はこの隠しフィールドに格納されている値を使用して、クリックしたボタンが有効なイベントを呼び出すようにします。有効でない場合、上記の例外が発生します。
EventValidation フィールドがレンダリングされる前にポストバックすると、特に問題が発生します。EventValidation が有効になっている場合 (デフォルトでは有効)、ポストバック時に ASP.net が隠しフィールドを認識しない場合も、例外が発生します。完全にレンダリングされる前にフォームを送信すると、EventValidation フィールドがまだレンダリングされていない可能性があるため、ASP.NET はクリックを検証できません。
回避策
次のように、enableEventValidation を false に設定し、viewStateEncryptionMode を Never に設定します。
<pages enableeventvalidation="false" viewstateencryptionmode="Never">
これには、検証と暗号化を無効にするという望ましくない副作用があります。一部のサイトではこれで問題ない場合もありますが、特に公開されているサイトではベスト プラクティスではありません。
詳細およびその他の回避策については、このブログ エントリを参照してください。