(1)検索処理メソッドを定義する
検索処理メソッドとして、引数に予約情報ID、戻り値に予約情報クラスを指定したメソッドを定義します。ここでのポイントは、引数についているSystem.Web.ModelBinding.QueryString属性です。この属性を引数に指定することで、クエリ文字列の同名の項目が自動的に引き渡されるようになります。
他に使用できるSystem.Web.ModelBinding名前空間の属性には、表1のようなものがあります。ObjectDataSourceコントロールのSelectParameters要素に指定するSystem.Web.UI.WebControls.Parameterクラスの派生クラスと、ほぼ同じ役割のものが指定できると考えてよいでしょう。
| 属性名 | 説明 |
|---|---|
| Control | 同一Webフォーム上のサーバーコントロールから値を指定 |
| Cookie | Cookieから値を設定 |
| Form | HTMLフォームから値を設定 |
| Profile | プロファイル情報(*1)から値を設定 |
| RouteData | ルーティングのデータ(*2)から値を設定 |
| Session | セッション状態から値を設定 |
| ViewState | ビューステートから値を設定 |
(2)Sessionから予約情報を取得する
削除処理を呼び出すと、その後検索処理も実行されてしまいます。すると、同時実行制御に用いているバージョン列の値も新たに取得されるため、その後の楽観的排他処理が正しく行えなくなります。
こういった問題を回避するため、処理対象データを再度データベースから取得しないよう、初めて検索した際にセッション状態に格納しておき、ここで取得、返却しています。
(3)ビジネスロジックの検索処理呼び出し
SelectReservationメソッドの引数を使ってビジネスロジックの検索処理を呼び出し、結果を返却します。
更新処理メソッド定義
次に、更新処理を行うメソッドを定義します(リスト4)。
// (1) 更新処理メソッド定義
public void UpdateReservation(Reservation reservation)
{
// (2) データバインドで設定できない項目を設定
reservation.MeetingRoomId = int.Parse(MeetingRoomDropDownList.SelectedValue);
var reserveDateFrom = DateTimeUtilities.ConvertDateTime(ReserveDateFromTextBox.Text, ReserveDateFromTimeTextBox.Text);
if (reserveDateFrom != null)
{
reservation.ReserveDateFrom = reserveDateFrom.Value;
}
var reserveDateTo = DateTimeUtilities.ConvertDateTime(ReserveDateToTextBox.Text, ReserveDateToTimeTextBox.Text);
if (reserveDateTo != null)
{
reservation.ReserveDateTo = reserveDateTo.Value;
}
// (3) 更新ロジック呼び出し
var logic = new ReservationLogic();
var result = logic.Update(reservation);
// (4) 結果判定
switch (result)
{
case ReservationLogic.Result.Success:
// 予約参照画面に戻る
Response.Redirect("~/Reservations.aspx");
break;
case ReservationLogic.Result.Overlap:
ModelState.AddModelError("", "予約期間が重なる予約がすでに登録されています。");
break;
case ReservationLogic.Result.Concurrency:
ModelState.AddModelError("", "他のユーザーにより先に更新されました。もう一度一覧画面より選択してやり直してください。");
break;
}
}
(1)更新処理メソッド定義
検索処理メソッドとして、引数にReservation型、戻り値にvoidを指定したメソッドを定義します。この辺りは、ビジネスロジックであるReservationLogicクラスのUpdateメソッドと一緒です。aspxファイルのFormViewコントロールでデータバインドを指定していると、この引数に値が設定されて渡されます。
なお、モデルバインドという名前は、このようにReservation型をモデルとみなして、モデルに値をバインドすることから来ています。
(2)データバインドで設定できない項目を設定
組み合わせ項目などでデータバインドで値を設定できない項目がある場合、ここで設定してしまいます。非モデルバインドではItemInserting/Updating/Deletingイベントを使って行っていた処理です(リスト2)。これらのイベントでは、イベント引数のValuesプロパティに項目名を指定して値を設定する必要がありましたが、モデルバインドを使えば直接プロパティに値を設定できるため、型安全に処理することができます。
(3)更新ロジック呼び出し
必要な値をモデルに設定した後、検索処理と同じようにビジネスロジックの更新処理を呼び出します。非モデルバインドと違ってビジネスロジックの戻り値を使うことができるため、処理結果を戻り値で戻すようにしています。
(4)結果判定
(3)で戻された結果をもとにエラー処理を行います。例では重なりデータエラーと同時実行エラーを検出してエラーを設定しています。Page.ModelStateプロパティは次回紹介するモデル検証の結果を格納するためのプロパティです。今回は詳細には触れませんが、エラーをAddModelErrorメソッドを使って設定ができることだけ覚えておいてください。
同じように削除処理メソッドも定義します。詳しくはサンプルを参照してください。
