データベース値の検証
ASP.NET Dynamic Dataを使えばデータベース編集用のシンプルなユーザーインターフェースを作成するのはごく簡単な作業になりますが、それでもやはり、大抵のアプリケーションではビジネスルールを作成してデータ入力を制御するという工程が必要です。もし可能であれば、そのための手だてはデータベースレベルから始めるのが最善の策です。例えば、必須のフィールドであれば、SQL Server内でそのように定義すべきです。あるいは、0~100の値しか受けつけないフィールドであれば、CHECKキーワードか、SQL Server Management Studioの[CHECK制約]ダイアログボックスを使って、フィールドに制約条件を直接追加すべきです。
ASP.NET Dynamic Dataアプリケーションでは、データベースレベルの制約の一部は自動的に適用されます。例えば必須フィールド(NOT NULL)の場合、実行時には、空白のままのときに自動的に検証エラーが発生します。しかし、モデルに反映されないもっと複雑な制約条件(CHECK制約など)の場合には、更新に失敗したという一般的なエラーとなってしまいます。どこに不備があるかをユーザーに明確に伝えたい場合には、ここでも属性を使用できます。
例えば、Range属性(System.ComponentModel.DataAnnotations名前空間で定義)を使用すると、整数または浮動小数点数のフィールドの最小値と最大値を指定できます。指定の仕方はScaffoldColumn属性やUIHint属性と同様です。
このほか、値のチェックに使用できる属性には、Required属性やRegularExpression属性があります。また、文字列の長さを制限できるStringLength属性もあります。一方、独自の検証コードを使用したい場合は、データモデルを拡張するメソッドを記述するという方法があります。例えば、ADO.NET Entitiesを使用している場合、フィールドを検証するためのパーシャルメソッド宣言がNorthwindModel.Designer.csファイルにあります。
例えば、従業員の入社日は必ず月曜日だというビジネスルールがある場合は、EmployeesクラスのOnHireDateChangingメソッドにコードを実装します。目的の処理は次のようなコードで実現できます。
public partial class Employees
{
partial void OnHireDateChanging(System.DateTime? value)
{
if (value.HasValue)
{
if (value.Value.DayOfWeek != DayOfWeek.Monday)
{
throw new Exception(
"The hire date must be a Monday");
}
}
}
}
しかし、この方法には1つ問題があります。OnChangingイベントはたびたび発生するイベントで、レコードの表示、編集、保存をするたびに発生するのです。このため、データベースの実際の値は必ず規則を満たしていなくてはなりません。規則を満たしていない場合はデータを表示できません。
代わりに、データベースに変更を保存するときにのみ値を検証したい場合には、もう少しコードを記述する必要があります。エンティティデータモデルクラス(このサンプルアプリケーションではNorthwindEntities)にはSavingChangesというイベントがあり、その中で処理を実行できます。検証規則のコードをこのイベントハンドラに記述します。
using System.Data;
using System.Data.Objects;
...
public partial class NorthwindEntities
{
partial void OnContextCreated()
{
this.SavingChanges
+= new EventHandler(MyHandlerForSavingChanges);
}
internal void MyHandlerForSavingChanges(
object sender, EventArgs e)
{
IEnumerable<ObjectStateEntry> changedEntities =
this.ObjectStateManager.
GetObjectStateEntries(EntityState.Added |
EntityState.Modified);
foreach (ObjectStateEntry entry in changedEntities)
{
if (entry.Entity is Employees)
{
Employees emp = (Employees)entry.Entity;
if (emp.HireDate.HasValue)
{
if (!(emp.HireDate.Value.DayOfWeek ==
DayOfWeek.Monday))
{
throw new Exception(
"The hire date must be a Monday");
}
}
}
}
}
}
このコードでは、まずOnContextCreatedパーシャルメソッドを実装し、SavingChangesイベントのイベントハンドラを追加します。イベントハンドラ本体(MyHandlerForSavingChanges内)では、追加または変更された全レコードをデータモデルから取り出し、ループ処理を行って、Employeesテーブルに関係するデータをピックアップします。該当するデータの場合は、HireDateフィールドの値をチェックし、月曜でない場合には例外を発生させます。
独自の検証コードの作成は特に難しいものではありませんが、使わなくても済むケースは多々あります。ASP.NET Dynamic Dataに用意されている属性は汎用性が高いからです。しかし、目的を満たせない場合には、ここで紹介した2つの方法を使って、独自の規則を記述するとよいでしょう。
まとめ
この記事では、ASP.NET Dynamic Dataを使用して、データベースの実用的なWebフロントエンドを短時間で作成する方法を見てきました。カスタマイズがほぼゼロの状態でも、管理目的程度なら十分使えるWebインターフェースを作成できます。さらに多少の開発を加えれば、多彩なユーザーに適したアプリケーションを効果的に作成できます。しかし、ASP.NET Dynamic Dataアプリケーションがすべてのニーズにぴったり適合するとは限りません。その場合には、ASP.NET Dynamic Dataアプリケーションを既存の標準的なASP.NET WebFormsアプリケーションに簡単に統合できるということも知っておくと役立ちます。さらには、グリッドを使用して、データのインプレース編集機能を有効にすることもできます。それには、Global.asax.csファイルで、10行ほどのコードをコメント化したりコメントから外したりします。具体的な方法については、ファイル内の説明を参照ください。
ASP.NET Dynamic Dataアプリケーションは、マスターページとCSSのスタイルを利用したユーザーインターフェース用ですので、作成したアプリケーションに変更を加えて、目的に合った外観と操作性を実現することも簡単です。さらに今後、そうしたカスタマイズはいっそう簡単になるはずです。次期バージョンのパブリックプレビュー版はCodePlexにも既に掲載されています。また、.NET Framework 4.0にはASP.NET Dynamic Dataがネイティブに統合されます。こうしたことから、ASP.NET Dynamic Dataの未来は明るいと言えます。現時点でも十分に役立つ機能であり、データベースのインターフェースを短時間で開発したいという多くの人のニーズを満たしています。
