英語で読む

次の方法で共有


クライアント・コールバックでデータベースの値を表示する方法

download1.gif サンプル コードのダウンロード (aspnettips_ClientCallback3.msi, 270 KB)

※このサンプルをお使いいただくためには、Visual Studio 2005 が必要です。

クライアント・コールバックでデータベースの値を表示する方法

ページをリロードせずにサーバーとやり取りする方法については、ページをリロードせずにサーバーとやり取りする方法クライアント・コールバックで複数の値をクライアントへ渡す方法で紹介しました。ここで紹介したサンプルは、クライアントに返す値として、サーバーのコードに埋め込んだ固定値を使っていました。
しかし、例えばデータベースのキーをサーバーへ投げ、該当するレコードの複数のフィールド値を取得したい場合には、どうすればよいでしょうか。そこで、今回は、クライアント・コールバックの機能を使い、サーバーにあるデータベースから値を受け取る方法を紹介します。

サンプル フォームの準備

サーバーで参照するデータベースは、図1 にあるものを使います。画像の番号、画像のパス、名前、色、の 4 つの値があるので、クライアント・コールバックで複数の値をクライアントへ渡す方法で紹介したサンプルに項目を 1 つ追加したページを用意します(リスト1、リスト2、および図1)。このページを元に値の参照先をデータベースに変更してたものを作成していきます。

図

図 1. IMAGE.mdb の IMGINFO テーブル

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="ClientCallback.aspx.vb" Inherits="_ClientCallback" %>
<!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>Sample Page</title>
    <script type="text/javascript">
        function ChangeImage()
        {
            var lb = document.MyForm.ListBox1;
            var imageNo = lb.options[lb.selectedIndex].value
            CallServer(imageNo, "");
        }
        function ReceiveServerData(rcvValue)
        {
        }
    </script>
</head>
<body>
    <form id="MyForm" runat="server">
         <br />
        <table border="1">
            <tr>
                <td>
                    画像番号
                </td>
                <td>
                    <asp:ListBox ID="ListBox1" runat="server"></asp:ListBox>
                </td>
            </tr>
            <tr>
                <td>
                    イメージ
                </td>
                <td>
                    <asp:Image ID="Image1" runat="server" ImageUrl="dummy.gif" />
                </td>
            </tr>
            <tr>
                <td>
                    名称
                </td>
                <td>
                    <asp:TextBox ID="TextImageName" Runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td>
                    色
                </td>
                <td>
                    <asp:TextBox ID="TextImageColor" Runat="server"></asp:TextBox>
                </td>
            </tr>
        </table>
  </form>
</body>
</html>

リスト1.ClientCallback.aspx

Partial Class _ClientCallback
    Inherits System.Web.UI.Page
    Implements System.Web.UI.ICallbackEventHandler
    Private returnValue As String
    Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim cbReference As String
        cbReference = Page.ClientScript.GetCallbackEventReference(Me, "arg", "ReceiveServerData", "context")
        Dim callbackScript As String = ""
        callbackScript &= "function CallServer(arg, context) { " & cbReference & "} ;"
        Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "CallServer", callbackScript, True)
    End Sub
    Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
    End Sub
    Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
        Return returnValue
    End Function
End Class

リスト2.ClientCallback.aspx.vb

図

図 2. ClientCallback.aspx のデザイナ画面

データを読み込む

リスト3のコード追加して、ページが読み込まれたときにデータベースからデータを取得します(リスト3 の赤文字)。データを取得した後に、取得したデータを元にリスト ボックスの項目が表示されるように設定します(リスト3 の青文字)。

Private myDataSet As Data.DataSet
    Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim cbReference As String
        cbReference = Page.ClientScript.GetCallbackEventReference(Me, "arg", "ReceiveServerData", "context")
        Dim callbackScript As String = ""
        callbackScript &= "function CallServer(arg, context) { " & cbReference & "} ;"
        Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "CallServer", callbackScript, True)
        ' DataSet を作成し、データを読み込む
        myDataSet = New Data.DataSet
        myDataSet.Locale = Globalization.CultureInfo.InvariantCulture
        LoadDataSet()
        ' リスト ボックスの設定
        ListBox1.DataSource = myDataSet
        ListBox1.DataTextField = "NAME"
        ListBox1.DataValueField = "ID"
        ListBox1.DataBind()
        ListBox1.Attributes.Add("onchange", "ChangeImage();")
    End Sub
    Public Function OpenDataBase() As Data.OleDb.OleDbConnection
        Dim Conn As New Data.OleDb.OleDbConnection()
        Conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + _
        AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "IMAGE.MDB"
        ' 取得したレコードを DataSet に設定
        Dim ds As New Data.DataSet
        ds.Locale = Globalization.CultureInfo.InvariantCulture
        Conn.Open()
        Return Conn
    End Function
    Public Sub LoadDataSet()
        Dim oleConn = OpenDataBase()
        Dim cmdSelect As New Data.OleDb.OleDbCommand("SELECT * FROM IMGINFO", oleConn)
        Dim oleDataAdapter As New Data.OleDb.OleDbDataAdapter(cmdSelect)
        oleDataAdapter.Fill(myDataSet)
        oleConn.Close()
        oleDataAdapter.Dispose()
        cmdSelect.Dispose()
        oleConn.Dispose()
    End Sub

リスト3.ClientCallback.aspx.vb に追加するコード

サーバー コールバック メソッドでレコードのフィールド数の値を結合する

リスト2 のコードでは、RaiseCallbackEvent に処理を実装していないので、ここでコールバック値を作成しましょう。今回は、テーブルに存在する全てのフィールドを改行コードで区切った文字列を作成します。作成する文字列のフォーマットは、次のようにフィールド名とフィールド値をセットにしたものを繋げたものとします。

[フィールド名] + vbLf + [フィールド値] + vbLf ...... 

この一連の処理を GetRecordString としてまとめ、RaiseCallbackEvent から呼出します(リスト4)。

  Public Function GetRecordString(ByVal keyId As String) As String
        Dim DataView As New Data.DataView(myDataSet.Tables(0))
        DataView.RowFilter = "ID=" + keyId
        Dim recordString As New StringBuilder()
        If DataView.Count > 0 Then
            ' 改行コードを区切りにして複数パラメータを渡す
            For count As Integer = 0 To DataView.Table.Columns.Count - 1
                ' フィールド名を設定
                recordString.Append(DataView.Table.Columns(count).ColumnName)
                recordString.Append(vbLf)      ' 改行コード
                ' 値を設定
                recordString.Append(DataView(0)(count).ToString)
                If count < DataView.Table.Columns.Count - 1 Then
                    recordString.Append(vbLf)  ' 改行コード
                End If
            Next
        End If
        DataView.Dispose()
        Return recordString.ToString
    End Function
    Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
        ' レコードの取得処理
        returnValue = GetRecordString(eventArgument)
    End Sub

リスト4.ClientCallback.aspx.vb に追加するコード

クライアント コールバック メソッドでレコードのフィールド数の値を分離する

リスト1 のコードでは、ReceiveServerData に処理を実装していないので、ここで受け取ったコールバック値をフィールド毎に分離します(リスト5)。分離した値は、フィールド名を添え字とする連想配列に格納します。こうすることで、フィールド名を指定した連想配列から値を取得することが出来ます。

   function ReceiveServerData(rcvValue)
        {
            // サーバーからの戻り値を配列に変換
            rcvValues = rcvValue.split(unescape("%0A"));
            // 列を添え字にした連想配列を作成
            var Row = new Object();
            for (count = 0; count < rcvValues.length; count=count+2){
                Row[rcvValues[count]] = rcvValues[count + 1];
            }
            // 値の表示
            if (Row["IMGPATH"] == ""){
                document.MyForm.Image1.src = "dummy.gif";
            }else{
                document.MyForm.Image1.src = Row["IMGPATH"];
            }
            document.MyForm.TextImageName.value = Row["NAME"];
            document.MyForm.TextImageColor.value = Row["COLOR"];
        }

リスト5.ClientCallback.aspx に追加するコード

完成した ClientCallback.aspx と ClientCallback.aspx.vb は、リスト6 およびリスト7 になり、実行結果は図3 のようになります。

   <%@ Page Language="VB" AutoEventWireup="false" CodeFile="ClientCallback.aspx.vb" Inherits="_ClientCallback" %>
<!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>Sample Page</title>
    <script type="text/javascript">
        function ChangeImage()
        {
            var lb = document.MyForm.ListBox1;
            var imageNo = lb.options[lb.selectedIndex].value
            CallServer(imageNo, "");
        }
        function ReceiveServerData(rcvValue)
        {
            // サーバーからの戻り値を配列に変換
            rcvValues = rcvValue.split(unescape("%0A"));
            // 列を添え字にした連想配列を作成
            var Row = new Object();
            for (count = 0; count < rcvValues.length; count=count+2){
                Row[rcvValues[count]] = rcvValues[count + 1];
            }
            // 値の表示
            if (Row["IMGPATH"] == ""){
                document.MyForm.Image1.src = "dummy.gif";
            }else{
                document.MyForm.Image1.src = Row["IMGPATH"];
            }
            document.MyForm.TextImageName.value = Row["NAME"];
            document.MyForm.TextImageColor.value = Row["COLOR"];
        }
    </script>
</head>
<body>
    <form id="MyForm" runat="server">
         <br />
        <table border="1">
            <tr>
                <td>
                    画像番号
                </td>
                <td>
                    <asp:ListBox ID="ListBox1" runat="server"></asp:ListBox>
                </td>
            </tr>
            <tr>
                <td>
                    イメージ
                </td>
                <td>
                    <asp:Image ID="Image1" runat="server" ImageUrl="dummy.gif" />
                </td>
            </tr>
            <tr>
                <td>
                    名称
                </td>
                <td>
                    <asp:TextBox ID="TextImageName" Runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td>
                    色
                </td>
                <td>
                    <asp:TextBox ID="TextImageColor" Runat="server"></asp:TextBox>
                </td>
            </tr>
        </table>
  </form>
</body>
</html>

リスト6.ClientCallback.aspx

Partial Class _ClientCallback
    Inherits System.Web.UI.Page
    Implements System.Web.UI.ICallbackEventHandler
    Private returnValue As String
    Private myDataSet As Data.DataSet
    Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim cbReference As String
        cbReference = Page.ClientScript.GetCallbackEventReference(Me, "arg", "ReceiveServerData", "context")
        Dim callbackScript As String = ""
        callbackScript &= "function CallServer(arg, context) { " & cbReference & "} ;"
        Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "CallServer", callbackScript, True)
        ' DataSet を作成し、データを読み込む
        myDataSet = New Data.DataSet
        myDataSet.Locale = Globalization.CultureInfo.InvariantCulture
        LoadDataSet()
        ' リスト ボックスの設定
        ListBox1.DataSource = myDataSet
        ListBox1.DataTextField = "NAME"
        ListBox1.DataValueField = "ID"
        ListBox1.DataBind()
        ListBox1.Attributes.Add("onchange", "ChangeImage();")
    End Sub
    Public Function OpenDataBase() As Data.OleDb.OleDbConnection
        Dim Conn As New Data.OleDb.OleDbConnection()
        Conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + _
        AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "IMAGE.MDB"
        ' 取得したレコードを DataSet に設定
        Dim ds As New Data.DataSet
        ds.Locale = Globalization.CultureInfo.InvariantCulture
        Conn.Open()
        Return Conn
    End Function
    Public Sub LoadDataSet()
        Dim oleConn = OpenDataBase()
        Dim cmdSelect As New Data.OleDb.OleDbCommand("SELECT * FROM IMGINFO", oleConn)
        Dim oleDataAdapter As New Data.OleDb.OleDbDataAdapter(cmdSelect)
        oleDataAdapter.Fill(myDataSet)
        oleConn.Close()
        oleDataAdapter.Dispose()
        cmdSelect.Dispose()
        oleConn.Dispose()
    End Sub
    Public Function GetRecordString(ByVal keyId As String) As String
        Dim DataView As New Data.DataView(myDataSet.Tables(0))
        DataView.RowFilter = "ID=" + keyId
        Dim recordString As New StringBuilder()
        If DataView.Count > 0 Then
            ' 改行コードを区切りにして複数パラメータを渡す
            For count As Integer = 0 To DataView.Table.Columns.Count - 1
                ' フィールド名を設定
                recordString.Append(DataView.Table.Columns(count).ColumnName)
                recordString.Append(vbLf)      ' 改行コード
                ' 値を設定
                recordString.Append(DataView(0)(count).ToString)
                If count < DataView.Table.Columns.Count - 1 Then
                    recordString.Append(vbLf)  ' 改行コード
                End If
            Next
        End If
        DataView.Dispose()
        Return recordString.ToString
    End Function
    Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
        ' レコードの取得処理
        returnValue = GetRecordString(eventArgument)
    End Sub
    Public Function GetCallbackResult() As String ImplementsSystem.Web.UI.ICallbackEventHandler.GetCallbackResult
        Return returnValue
    End Function
End Class

リスト7.ClientCallback.aspx.vb

Cc719207.ClientCallback3_fig03(ja-jp,MSDN.10).gif

図 3. ClientCallback.aspx の実行結果