クライアント・コールバックでデータベースの値を表示する方法
サンプル コードのダウンロード (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
図 3. ClientCallback.aspx の実行結果