Parameterクラス
実際にObjectDataSource
はどのように設定されているのでしょうか?
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="Exec" TypeName="Power"> <SelectParameters> <asp:QueryStringParameter DefaultValue="0" Name="value" QueryStringField="id" Type="Int32" /> </SelectParameters> </asp:ObjectDataSource>
ObjectDataSource
はSelect、Insert、Update、Deleteの各SQLコマンドに合わせた形で、個別のパラメータを持っています。今回のように表示させるためだけの場合にはSelectParameters
を設定します。SelectParameters
の中にはQueryStringParameter
というQueryString
から値を設定するためのパラメータが設定されており、今回の設定はQueryStringField
のid
という値をInt32
としてvalue
に利用するということが明記されています。
上の図は、クラスダイアグラムで見た関係です。SelectParameters
などは、ParameterCollection
を利用しており、QueryStringParameter
などはParameter
クラスを利用していることがわかります。このParameter
クラスはDataSource
を利用する上で非常に重要な位置づけをしめており、DataSource
へのパラメータ処理を一切記述しなくても良いのは、すべてこのクラスのおかげです。
Parameter
クラスは.NET Framework 2.0では6つのクラスに派生しています。
クラス名 | 役割 |
ControlParameter | コントロールの値からパラメータを利用します。 |
CookieParameter | クッキーの値からパラメータを利用します。 |
FormParameter | フォームでポストされた値からパラメータを利用します。 |
ProfileParameter | ASP.NET 2.0のプロファイル機能からパラメータを利用します。 |
QueryStringParameter | 呼び出しURLで設定された値からパラメータを利用します。 |
SessionParameter | セッションの値からパラメータを利用します。 |
これらの.NET Framework 2.0でサポートされているParameter
クラスで、かなりの作業を自動化できます。ただし、少し複雑なパラメータ設定を行おうとすると自由度の高いパラメータがないことに気づきます。そこで、続いてはParameter
クラスが値を必要とする瞬間にイベントを発生させるクラスを作成してみましょう。
DelegateParameterクラスを作成してみよう
Parameter
クラスは値を決定する際にEvaluate
というメソッドで行います。このEvaluate
をオーバーライドすれば望みのものが作成できそうです。今回はASP.NETプロジェクト内に「App_Code」という特殊なフォルダを作成してその中に作成します。外部DLLを使うやり方でももちろん同じことが可能ですが、以降の説明はApp_Code
を前提とします。
using System; using System.Collections.Generic; using System.Text; using System.Web; using System.Web.UI; //名前空間を宣言しないとASPXからの呼び出しができません。 namespace Wankuma.Web.UI.WebControls { //デリゲートを定義します。戻り値用のパラメータがありますが、 //それ以外の2つはParameter.Evaluateにあわせてあります。 public delegate void WebParameterEvaluate( out object ReturnValue, HttpContext context, Control control); //DelegateParameterクラスの宣言です public class DelegateParameter : System.Web.UI.WebControls.Parameter { //イベントを宣言します public event WebParameterEvaluate DelegateEvaluator; //値を必要とする際に呼び出されるメソッドをオーバーライドします protected override object Evaluate( System.Web.HttpContext context, System.Web.UI.Control control) { if (this.DelegateEvaluator == null) { //イベント宣言がされていない場合にはnullを戻します return null; } else { //戻り値用の変数を宣言します object returnvalue = null; //イベントを呼び出します this.DelegateEvaluator(out returnvalue, context, control); //戻り値をそのまま返します return returnvalue; } } } }
Imports Microsoft.VisualBasic '名前空間を宣言しないとASPXからの呼び出しができません。 Namespace Wankuma.Web.UI.WebControls 'デリゲートを定義します。戻り値用のパラメータがありますが、 'それ以外のつはParameter.Evaluateにあわせてあります。 Public Delegate Sub WebParameterEvaluate(ByRef ReturnValue As Object, _ ByVal context As HttpContext, ByVal control As Control) 'DelegateParameterクラスの宣言です Public Class DelegateParameter Inherits Parameter 'イベントを宣言します Public Event DelegateEvaluator As WebParameterEvaluate '値を必要とする際に呼び出されるメソッドをオーバーライドします Protected Overrides Function Evaluate( _ ByVal context As HttpContext, _ ByVal control As Control) As Object '戻り値用の変数を宣言します Dim ReturnValue As Object = Nothing 'イベントを呼び出します RaiseEvent DelegateEvaluator(ReturnValue, context, control) '戻り値をそのまま返します Return ReturnValue End Function End Class End Namespace
このようにEvaluate
をオーバーライドし、完全に新しいイベントに処理を委譲しています。このイベントを利用するように先ほどのページを変更してみましょう。
DelegateParameterを利用してみよう
先ほどはQueryString
のid
の値をそのまま2乗していたので、今回は2倍(×2)にしてから2乗するようにしてみましょう。×2する部分でDelegateParameter
を利用します。まずは.aspxファイルの先頭に次のような記述を行います。
<%@ Register TagPrefix="wankuma" Namespace="Wankuma.Web.UI.WebControls" %>
ここで先ほど設定した名前空間を必ず指定します。独自の名前空間を設定された場合にはその名前空間を記述してください。
次にSelectParameters
を変更します。
<SelectParameters> <wankuma:DelegateParameter Name="value" Type="Int32" OnDelegateEvaluator="kakeru2" /> </SelectParameters>
このように設定することにより、kakeru2
というメソッドをイベント登録します。
続いてkakeru2
の実体を定義します。
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class Default2 : System.Web.UI.Page { public void kakeru2(out object ReturnValue, HttpContext context, Control control) { int value; if (context.Request["id"] == null ) { value = 0; } else { if (int.TryParse(context.Request["id"], out value) == false) { value = 0; } } ReturnValue = value * 2; } }
Partial Class Default2 Inherits System.Web.UI.Page Public Sub Kakeru2(ByRef ReturnValue As Object, _ ByVal context As HttpContext, ByVal control As Control) Dim value As Integer If (context.Request("id") Is Nothing) Then value = 0 Else If (Integer.TryParse(context.Request("id"), value) = False) Then value = 0 End If End If ReturnValue = value * 2 End Sub End Class
実行してみよう
新しい処理は「default2.aspx」というページに作成したので、「default2.aspx」を呼び出してみましょう。URLは「http://localhost:2582/cs/default2.aspx?id=10」と入力します(ただし、実際のURLは若干異なる場合があります)。
id
に指定した「10」が、2倍になってから2乗され、無事「400」が表示されています。
最後に
いかがでしたか? Parameter
クラスの継承はさまざまなメリットを導き出してくれます。例えば、独自認証情報からのユーザーIDの設定(ProfileParameter
の独自版)、証跡の保持のためにRequest
の加工設定、Session
に格納されている独自クラスの情報抜き出し設定などです。うまくParameter
の派生クラスを作ることにより、皆さんも一緒にノーコーディングプログラムを目指しましょう。