[ ASP.NET ] 画面操作せずにポストバック ( __doPostBack 関数 )

Pocket

ASP.NET で作成される HTML ファイルには、以下のような  Javascript が記述されていることがあります。

スポンサーリンク

<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />

<script type="text/javascript">
//<![CDATA[ 
var theForm = document.forms['form1']; 
if (!theForm) { 
    theForm = document.form1; 
} 
function __doPostBack(eventTarget, eventArgument) { 
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) { 
        theForm.__EVENTTARGET.value = eventTarget; 
        theForm.__EVENTARGUMENT.value = eventArgument; 
        theForm.submit(); 
    } 
} 
//]]>
</script>

ここで ASP.NET によって追加されている __doPostBack 関数は、イベントを発生させたコントロールとそのパラメーターを隠しフィールドに設定しフォームを submit (ポストバック) しています。Web サーバでは、その隠し項目の内容からイベントを区別し各々のコントロールに紐付けられているイベントハンドラを実行しています。

自前で __doPostBack 関数を呼び出す

実際に、__doPostBack 関数を呼び出してみようと思います。ここでは、以下のボタンコントロールとテキストボックスコントロールを設置した画面を使用します。

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="WebApplication1._Default" EnableEventValidation="false" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>画面操作なしでポストバック</title>
</head>
<body>
<form id="form1" runat="server">
    <div>
        <asp:Button ID="Button1" runat="server" Text="Button" UseSubmitBehavior="false" />
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    </div>
</form>
</body>
</html>

ここで、注意しなければならないのが @ Page ディレクティブの EnableEventValidation を false に設定していることです。また、asp:Button タグの UseSubmitBehavior プロパティを false にしているのは、UseSubmitBehavior が true ( デフォルト ) の場合、asp:Button は type が submit の input タグに変換され、__doPostBack が自動生成されなかったためです。

サンプルコード

以下がサンプルコードになります。画面作成時に __doPostBack 関数を呼び出す Javascript を画面に埋め込んでいます。__doPostBack 関数の第一引数にはボタンコントロールの UniqueID プロパティを設定する点がポイントです。

VB.NET

    ''' ページロード
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        ' ポストバック時はリターン
        If (IsPostBack = True) Then Return

        ' スクリプトを埋め込み、ポストバックさせる
        Dim sScript As String = "__doPostBack('" + Button1.UniqueID + "','parameter string');"
        Page.ClientScript.RegisterStartupScript(Me.GetType(), "key", sScript, True)

    End Sub

    ''' ボタンクリック
    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click

        TextBox1.Text = "Button1.Click"

        ' パラメータを取得する
        Dim param As String = Request.Form("__EVENTARGUMENT")

    End Sub

C#

    /// ページロード
    protected void Page_Load(object sender, EventArgs e)
    {
        // ポストバック時はリターン
        if (IsPostBack == true) { return; }

        // スクリプトを埋め込み、ポストバックさせる
        string sScript = "__doPostBack('" + Button1.UniqueID + "','parameter string');";
        Page.ClientScript.RegisterStartupScript(this.GetType(), "key", sScript, true);
    }

    /// ボタンクリック
    protected void Button1_Click(object sender, EventArgs e)
    {
        TextBox1.Text = "Button1.Click";
            
        // パラメータを取得する
        string param = Request.Form["__EVENTARGUMENT"];
    }
@ Page ディレクティブの EnableEventValidation プロパティ

サンプルコードで使用した画面の @ Page ディレクティブの EnableEventValidation プロパティを true にすると以下の例外が発生します。詳細は『 Page.EnableEventValidation プロパティ 』 で確認できますので参照ください。また、ここで使用した画面もこの例外を回避するために EnableEventValidation プロパティ を設定しました。本来はこのように自前で __doPostBack 関数を呼び出す必要はないでしょう。

発生する例外の内容

説明: 現在の Web 要求を実行中に、ハンドルされていない例外が発生しました。エラーに関する詳細および例外の発生場所については、スタック トレースを参照してください。

例外の詳細: System.ArgumentException: 無効なポストバックまたはコールバック引数です。イベントの検証は、構成の 、またはページの <%@ Page EnableEventValidation=”true” %> を使用して有効にされます。セキュリティの目的により、この機能は、イベントをポストバックまたはコールバックする引数が、それらを最初に表示したサーバー コントロールから発行されていることを確認します。データが有効であり、予期されている場合、検証のためのポストバックまたはコールバック データを登録するために ClientScriptManager.RegisterForEventValidation メソッドを使用してください。

参考

 

スポンサーリンク


Pocket

Leave a Comment

Your email address will not be published. Required fields are marked *