問題の説明: これは、多くの ASP.NET 初心者が直面し、投稿し、質問する一般的な問題の 1 つです。通常、彼らは以下のようなエラー メッセージを投稿し、何をしようとしているのかについてあまり共有せずに解決策を探します。
[ArgumentException: 無効なポストバックまたはコールバック引数。イベントの検証は、設定で使用するか、ページで <%@ Page EnableEventValidation="true" %> を使用して有効にします。セキュリティ上の理由から、この機能は、ポストバック イベントまたはコールバック イベントへの引数が、それらを最初にレンダリングしたサーバー コントロールから発信されていることを確認します。データが有効で期待される場合は、ClientScriptManager.RegisterForEventValidation メソッドを使用して、検証のためにポストバックまたはコールバック データを登録します。]
エラー スタック トレース自体は、eventvalidation をオフに設定することで迅速な解決策を提案しますが、セキュリティ ホールを開くため、推奨される解決策ではありません。なぜそれが起こったのか、そしてその根本的な問題を解決/処理する方法を知ることは常に良いことです.
評価: イベントの発生元が関連するレンダリングされたコントロールであるかどうか (クロス サイト スクリプトなどではないかどうか) を検証するために、イベントの検証が行われます。コントロールはレンダリング中にイベントを登録するため、イベントはポストバックまたはコールバック中に (__doPostBack の引数を介して) 検証できます。これにより、不正または悪意のあるポストバック リクエストとコールバックのリスクが軽減されます。
参照: MSDN: Page.EnableEventValidation プロパティ
上記に基づいて、私が直面した、または議論で問題を提起したと聞いた可能性のあるシナリオは次のとおりです。
考えられる解決策: フォームを送信する前に、JavaScript を使用して角かっこを HTML エンコードします。つまり、「<」を置き換えます。「<」で および「>」と「>」</p>
function HTMLEncodeAngularBrackets(someString)
{
var modifiedString = someString.replace("<","<");
modifiedString = modifiedString.replace(">",">");
return modifiedString;
}
ケース #2: 実行時にクライアントのコントロールを変更するクライアント スクリプトを作成すると、ダングリング イベントが発生する可能性があります。例として、内部コントロールがポストバック用に登録されているが、外部コントロールで行われた操作のために実行時に非表示になっている組み込みコントロールがある場合があります。これは、複数のフォームタグが原因で同じ問題を探しているときに、Carlo によって書かれた MSDN ブログで読んだものです。
考えられる解決策: ページの Render メソッド内でイベント検証用のコントロールを手動で登録します。
protected override void Render(HtmlTextWriter writer)
{
ClientScript.RegisterForEventValidation(myButton.UniqueID.ToString());
base.Render(writer);
}
前述のように、報告された他の一般的なシナリオの 1 つ (これと同じカテゴリに分類されるようです) は、あるフォーム タグがサーバー上で実行される別のフォーム タグに埋め込まれているページを構築することです。それらのいずれかを削除すると、フローが修正され、問題が解決されます。
ケース #3: ポストバックごとに実行時にコントロールまたはコマンドを再定義/インスタンス化すると、それぞれの/関連するイベントがトスになる可能性があります。簡単な例として、すべてのページロード (ポストバックを含む) でデータグリッドを再バインドすることが考えられます。再バインド時にグリッド内のすべてのコントロールが新しい ID を持つため、データグリッド コントロールによってトリガーされたイベント中に、ポストバック時にコントロール ID が変更され、イベントが正しいコントロールに接続されず、問題が発生する可能性があります。
考えられる解決策: これは、すべてのポストバックでコントロールが再作成されないようにすることで簡単に解決できます (ここで再バインド)。Page プロパティ IsPostback を使用すると、簡単に処理できます。ポストバックごとにコントロールを作成する場合は、ID が変更されていないことを確認する必要があります。
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostback)
{
// Create controls
// Bind Grid
}
}
結論: 前述のように、簡単で直接的な解決策は、Page ディレクティブまたは Web.config ファイルに enableEventValidation="false" を追加することですが、推奨されません。実装と原因に基づいて、根本原因を見つけ、それに応じて解決策を適用します。