突合せエラー
突合せエラーの対処は、DBアクセスなどの外部プロセスを呼び出す処理が必要な関係上、第1回、第2回で説明した「ロジック層」で行うことになります。「プレゼンテーション層」であるaspxファイル、および分離コードファイルでは、ロジック層の実行結果を判定し、適切なエラーメッセージを表示することになります。
ロジック層からプレゼンテーション層への処理結果を戻す方法には、メソッドの戻り値を使う方法と例外を使う方法の2種類があります。
まず、メソッドの戻り値を使う方法ですが、第1回、第2回で紹介したデータバインドを活用したロジック層の呼び出しではなく、自前でロジック層の呼び出しを行う際に採用します。
具体的なコード例を示します。
protected void InsertButton_Click(object sender, EventArgs e)
{
// ... 省略 単体入力チェック後
// 追加処理
var logic = new MeetingRoomLogic();
var result = logic.Insert(meetingRoom); // (1)
// (2)
switch (result)
{
case MeetingRoomLogic.InsertMeetingRoomResult.MeetingRoomNameDuplicated:
// 同じ名前で登録済み
PageUtilities.ShowErrorMessage(this, "既に同じ名前の会議室が登録されています。");
return;
}
Response.Redirect("~/MeetingRooms.aspx");
}
(1) ロジック層の処理結果を受け取る
ロジック層の実行結果を、ロジック層のクラスの内部に定義した列挙型として受け取ります。こうすることで、その列挙型が結びついているロジック層のクラスが明確になります。
(2) 処理結果を判定する
戻り値を判定し正常終了でないときは、適切なメッセージを表示します(PageUtilities.ShowErrorMessageメソッドは、サンプルに独自に定義したメッセージ表示処理です)。
また、メッセージを表示したらそこで処理を中断させます。
次に例外を用いた方法は、データバインドを活用したロジック層の呼び出しを行う際に採用します。
その理由は、データバインドを用いてロジック層を呼び出した際、戻り値を判定し、なおかつ入力値を保持することが困難なためです。
具体的なコード例を示します。
protected void MeetingRoomsFormView_ItemUpdated(object sender, FormViewUpdatedEventArgs e)
{
if (e.Exception != null) // (1)
{
// (2)
if (e.Exception.InnerException is MeetingRoomLogic.DuplicateMeetingRoomException)
{
// 同じ名前で登録済み
PageUtilities.ShowErrorMessage(this, "既に同じ名前の会議室が登録されています。");
// (3) 入力値を維持
e.KeepInEditMode = true;
// (4) 例外を処理済みとマーク
e.ExceptionHandled = true;
return;
}
}
Response.Redirect("~/MeetingRooms.aspx");
}
(1) 例外の有無を判定する
ロジック層の呼び出し時に例外が発生していた場合、FormViewコントロールのItemUpdatedイベントのイベント引数のExceptionプロパティが設定されています。
(2) 例外の種類を判定する
発生した例外は、InnterExceptionプロパティに設定されていますので、その型を判定して適切なメッセージを表示します。
(3) 入力値を維持する
メッセージを表示してもそのままだと入力した値が失われ、変更前の値が再表示されてしまいます。
これを避けるため、KeepInEditModeプロパティにtrueを設定します。
(4) 例外を処理済みとマークする
e.ExceptionHandledプロパティにtrueを設定することで、発生した例外を処理済みとマークします。これを行わないと、例外が未処理と判断されてしまうため、システムエラーとして扱われてしまいます。
原則としてはメソッドの戻り値を使うようにし、データバインドにより業務ロジックを呼び出す必要があれば、例外を使用することを検討しましょう。
