モデル・バインディングとは、クライアントとサーバの間でやりとりするデータに対して、ビューやデータベースなどの各レイヤで、型変換やマッピング、そして値の検証などを行ってくれる一連の機能を指す。
このような仕組みとしては以前から、Webフォーム・コントロールのデータ・バインディングやObjectDataSource、そしてASP.NET MVCのモデル・バインディングなどが存在していたが、ASP.NET 4.5では、これらの概念を拡張、包括した仕組みとしてのモデル・バインディングが提供されるようになった。
ASP.NET 4.5では、モデル・バインディングの仕組みとして、コードによるデータ選択を簡単に行う方法が新たに実装された。この仕組みを使うには、コントロールのSelectMethodプロパティに、コードビハインド側で実装しているデータ取得メソッド名を指定するだけでよい。
<asp:GridView ID="OrderGridView" runat="server"
ItemType="ASPDotNet4_5Part2.Order" AutoGenerateColumns="false"
SelectMethod="GetOrders">
<Columns>
<asp:BoundField DataField="Order_ID" HeaderText="ID" />
<asp:TemplateField HeaderText="注文日" SortExpression="Order_Date">
<ItemTemplate>
<%# String.Format("{0:yyyy/M/d}", Item.Order_Date) %>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Customer.Company_Name" HeaderText="会社名" />
</Columns>
</asp:GridView>
上記の例では、SelectMethodプロパティに「GetOrders」を指定している。ここで指定したメソッドは、IEnumerableオブジェクトまたはIQueryableオブジェクトを返す必要がある。さらに、ItemTypeプロパティを指定した場合には、データ選択メソッドはItemTypeに指定した型を含むジェネリック型を返すべきだ。従って、上記の例ではページ・クラス側のコードでは、IEnumerable<Order>オブジェクトかIQueryable<Order>オブジェクトを返す必要がある。
次に、ページ・クラス側のコードを見てみよう。この例ではNorthwindサンプル・データベースを使用している。GetOrdersメソッドは、データベースに登録されている全てのOrderの一覧を返すだけだ。
public IQueryable<Order> GetOrders()
{
var db = new NorthwindEntities();
return db.Orders;
}
SelectMethodプロパティに指定したメソッドがIQueryableオブジェクト(もしくはIQueryable<T>オブジェクト)を返すことで、クエリが実際に実行される前にそれを操作できるようになっている。この例であれば、GridViewコントロールは実行前にソートとページングのためのクエリを追加できる。ソートやページングの操作はデータベース側で行われるため、ソートやページングなどの処理を効率的かつ簡単に実装できる。
以下では、GridViewコントロールでソートとページングを行えるように実装をした場合の例を示す。
<asp:GridView ID="OrderGridView" runat="server" DataKeyNames="Order_ID"
AllowSorting="true" AllowPaging="true" PageSize="5"
ItemType="ASPDotNet4_5Part2.Order" AutoGenerateColumns="false"
SelectMethod="GetOrders">
<Columns>
<asp:BoundField DataField="Order_ID" HeaderText="ID" />
<asp:TemplateField HeaderText="注文日" SortExpression="Order_Date">
<ItemTemplate>
<%# String.Format("{0:yyyy/M/d}", Item.Order_Date) %>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Customer.Company_Name" HeaderText="会社名" />
</Columns>
</asp:GridView>
ここまでの例では、全てのデータを取得するのみだったが、何らかのキーワードを指定しての絞り込み検索も行える。絞り込み検索を行うには、System.Web.ModelBinding名前空間にあるQueryStringAttributeクラスを使用する。
using System.Web.ModelBinding;
……省略……
public IQueryable<Order> GetOrders([QueryString]int? orderId)
{
IQueryable<Order> query = db.Orders;
if (orderId.HasValue && orderId > 0)
{
query = query.Where(o => o.Order_ID == orderId);
}
return query;
}
モデル・バインディングでは、メソッドの引数に[QueryString]属性が付けられた場合、実行時に[QueryString]属性を持つパラメータ名に対応する値をクエリ文字列から取得して、必要に応じて型変換を行った後にメソッドに渡す。
入力ソースとしては、以下のものがあらかじめ用意されている。これらは「Value Provider」と呼ばれ、開発者がカスタマイズすることもできる。
属性 | 説明 |
---|---|
Control | コントロールから取得できる値 |
Cookie | クッキーから取得できる値 |
Form | フォームのフィールドから取得できる値 |
Profile | プロフィールから取得できる値 |
QueryString | クエリ文字列から取得できる値 |
RouteData | ルーティングデータから取得できる値 |
Session | セッションから取得できる値 |
UserProfile | ユーザープロファイルから取得できる値 |
ViewState | ViewStateから取得できる値 |
入力ソースとして使用できるデータ |
デフォルトでは、引数名はValue Providerが該当する値を見付けるためのキーとして使用される。上記の例ではクエリ文字列の中からパラメータ名が「orderId」として指定された値を使用する。例えば「~/default.aspx?orderId=10000」というクエリ文字列が指定されれば、GetOrdersメソッドの引数「orderId」の値には「10000」が渡される。
また、クエリ・パラメータ名とメソッドの引数名は別の名前にもできる。その場合にはQueryString属性の引数としてカスタム・キー名を指定する。以下は、クエリ・パラメータ名に“orderId”ではなく“q”を使用する場合の例である。
public IQueryable<Order> GetOrders([QueryString("q")]int? orderId)
{
……省略……
}
このようにモデル・バインディングは、値の読み込み、Nullチェック、必要な型への変換、その変換が成功したかどうかなどの処理をわずかな手間で実行してくれる。
Copyright© Digital Advantage Corp. All Rights Reserved.