次の方法で共有


方法 : データ モデルのデータ フィールド検証をカスタマイズする

更新 : 2008 年 7 月

ASP.NET Dynamic Data では、データ モデルに対するデータ検証をカスタマイズして拡張できます。このトピックでは、データ モデルにデータ フィールドの検証機能を追加する方法について説明します。次のような方法があります。

  • 対象フィールドに Dynamic Data の System.ComponentModel.DataAnnotations 属性を適用することによって、個々のデータ フィールドの検証をカスタマイズする。これらの属性は、範囲のチェックや必須フィールドなど、一般的な検証パターンを定義します。このアプローチでは、定義済みの検証チェックを使用でき、コーディングはほとんど必要ありません。Dynamic Data が既に備えている検証機能を補足する必要があり、既定の System.ComponentModel.DataAnnotations 属性で必要な要件を満たすことができる場合は、このアプローチを使用してください。

    Cc488527.alert_note(ja-jp,VS.90).gifメモ :

    カスタム検証属性を作成することもできます。これにより、System.ComponentModel.DataAnnotations 属性で提供される検証を拡張できます。これは、標準の属性では特定のデータ フィールドに対する検証要件を満たせない場合に役立ちます。詳細については、「方法 : データ モデルでカスタム属性を使用してデータ フィールドの検証をカスタマイズする」を参照してください。

  • データ フィールドの変更を処理する部分クラスのメソッドをオーバーライドする (または対応するイベントを処理する) ことによって、個々のデータ フィールドの検証をカスタマイズする。このアプローチでは、個々のフィールドに対する検証とビジネス ロジックを追加できます。

  • OnValidate メソッドをオーバーライドする (または Validate イベントを処理する) ことによって、すべてのデータ フィールドの検証をカスタマイズする。このメソッドは、テーブル内のいずれかのデータ フィールドが処理されると呼び出されます。これは、個々のフィールドに対する検証を追加するよりも一般的なアプローチです。複数のデータ フィールドに対して同じ検証ロジックを適用できる場合に有効です。複数のフィールドが関係する検証チェックを実行することもできます。

データ モデルでスローされる検証例外は、DynamicValidator コントロールによってキャッチされます。ページに DynamicValidator コントロールが存在する場合は、そのページにエラーを表示できます。

  • データ モデルに対してどのような検証チェックを追加する場合でも、データ モデル内のテーブル クラスを拡張する部分クラスを作成する必要があります。検証チェックは、その部分クラスに対して追加することになります。

この機能のオンライン サンプルを実行してください。

検証用の部分クラスの作成

データ モデル層での検証をカスタマイズするには、あらかじめ、データ モデルを拡張する部分クラスを実装しておく必要があります。これにより、次の操作が可能になります。

  • 属性を通じてメタデータ情報を追加することで、検証をカスタマイズする。

  • 部分クラスのメソッドを実装して独自の検証ロジックを作成することで、検証をカスタマイズする。

検証用の部分クラスを作成するには

  1. ソリューション エクスプローラで、[App_Code] フォルダを右クリックし、[新しい項目の追加] をクリックします。

  2. [Visual Studio にインストールされたテンプレート][クラス] をクリックします。

    [名前] ボックスに、検証の追加対象となるデータ テーブルの名前を入力します。

    クラス名は、テーブルを表すエンティティ クラス名と一致させる必要があります。たとえば、Customers テーブルに検証を追加する場合は、ファイルに「Customer.cs」(Visual C# の場合) または「Customer.vb」(Visual Basic の場合) という名前を付け、クラス名を「Customer」にする必要があります。

  3. クラス定義に Partial キーワード (Visual Basic の場合) または partial キーワード (Visual C# の場合) を追加して部分クラスにします。

    次の例は、更新後のクラス宣言を示しています。

    public partial class Customer {
    
    }
    
    Partial Public Class Customer
    
    End Class
    
  4. Visual C# でクラスを作成する場合は、既定のコンストラクタを削除します。

  5. Imports キーワード (Visual Basic の場合) または using キーワード (Visual C# の場合) を使用して、System.Web.DynamicData 名前空間と System.ComponentModel.DataAnnotations 名前空間への参照を追加します。次に例を示します。

    using System.Web.DynamicData;
    using System.ComponentModel.DataAnnotations;
    
    Imports System.Web.DynamicData
    Imports System.ComponentModel.DataAnnotations
    
  6. 同じファイル内に、関連メタデータ クラスとして機能するクラスを追加します。このクラスには、クラス名として有効であり、まだ使用されていない名前であれば、任意の名前を付けることができます。

    メタデータのクラス宣言を次の例に示します。

    [C#]

    public class CustomerMetadata
    {
    
    }
    
    Public Class CustomerMetadata 
    
    End Class
    

    関連メタデータ クラスは、検証属性の適用先となるオブジェクトを提供します。

  7. 部分クラス定義に MetadataTypeAttribute 属性を適用します。属性のパラメータには、前の手順で作成した関連メタデータ クラスの名前を使用します。

    属性が適用された部分クラス定義を次の例に示します。

    [MetadataType(typeof(CustomerMetadata))]
    public partial class Customer {
    
    }
    
    <MetadataType(GetType(CustomerMetadata))> _
    Partial Public Class Customer
    
    End Class
    

属性を使用した検証のカスタマイズ

ここでは、Dynamic Data の System.ComponentModel.DataAnnotations 属性で提供される既定の検証規則を使用して、検証をカスタマイズする方法を示します。

検証属性を使用して特定のデータ フィールドを検証するには

  1. メタデータ クラスに、検証するデータ フィールドに対応する名前のプロパティ (フィールド) を作成します。

  2. このプロパティに、System.ComponentModel.DataAnnotations 名前空間のいずれかの属性を適用します。

    次の例では、関連メタデータ クラスの Title データ フィールドに System.ComponentModel.DataAnnotations.RequiredAttribute 属性を適用しています。ユーザーが空の文字列を入力すると、IsValid メソッドから検証例外がスローされ、エラー メッセージが生成されます。

    Cc488527.alert_note(ja-jp,VS.90).gifメモ :

    RequiredAttribute 属性を適用すると、データベースで値が必須とされていない場合でも、ユーザーに値の入力を強制することができます。

    public class CustomerMetadata
    {
      [Required()]
      public object Title;
    }
    
    Public Class CustomerMetadata 
      <Required()> _
      Public Title As Object
    End Class
    

部分クラスのメソッドによる個々のデータ フィールドに対する検証のカスタマイズ

ここでは、個々のデータ フィールドに対する変更を処理する部分クラスのメソッドをオーバーライドすることで、検証をカスタマイズする方法について説明します。この種類の検証では、System.ComponentModel.DataAnnotations 属性に実装されている Dynamic Data の組み込みのチェックには頼らずに、独自の規則を作成して検証を実行できます。

部分クラスのメソッドを使用して特定のデータ フィールドを検証するには

  1. データ フィールドに対する変更を処理する部分クラスのメソッドをオーバーライドします。

  2. カスタムの検証ロジックを追加します。

    次の例では、部分クラス Customer の OnTitleChanging メソッドをオーバーライドしています。このメソッドは、Customer データ テーブルの Title フィールドが変更されようとしているときに呼び出されます。この例のコードでは、ユーザーによって入力された新しいタイトルが、英大文字で始まっているかどうかをチェックしています。データが検証で不合格になると、メソッドから例外がスローされます。検証対象の値は、唯一のパラメータとしてメソッドに渡されます。パラメータの型は、検証するデータの型に合わせる必要があります。

    Cc488527.alert_note(ja-jp,VS.90).gifメモ :

    データ モデルでスローされる検証例外は、DynamicValidator コントロールによってキャッチされます。ページに DynamicValidator コントロールが含まれていれば、そのページにエラーを表示できます。

    public partial class Customer 
    {
      partial void OnTitleChanging(string value) 
      {
        if (!Char.IsUpper(value[0])) {
          throw new ValidationException(
           "Title must start with an uppercase letter.");}
        }
    }
    
    Public Partial Class Customer
      Private Sub OnTitleChanging(ByVal value As String)
        If Not [Char].IsUpper(value(0)) Then
          Throw New ValidationException( _
            "Title must start with an uppercase letter.")
        End If
      End Sub
    End Class
    

部分クラスのメソッドによるすべてのデータ フィールドに対する検証のカスタマイズ

ここでは、テーブル内のすべてのデータ フィールドに対する変更を処理する部分クラスのメソッドをオーバーライドすることで、検証をカスタマイズする方法について説明します。この種類の検証では、System.ComponentModel.DataAnnotations 属性に実装されている Dynamic Data の組み込みのチェックには頼らずに、独自の規則を作成して検証を実行できます。複数のデータ フィールドに対して同じ検証ロジックを適用できる場合に有効です。複数のフィールドが関係する検証チェックを実行することもできます。

部分クラスのメソッドを使用して任意のデータ フィールドを検証するには

  1. 部分クラスのメソッドである OnValidate をオーバーライドします。このメソッドは、テーブル内の任意のデータ フィールドが変更されたときに呼び出されます。

  2. カスタムの検証ロジックを追加します。

    OnValidate メソッドがどのようにオーバーライドされるかを次の例に示します。この例では、ユーザーによって入力された姓と名が、英大文字で始まっているかどうかをチェックしています。データが検証で不合格になると、メソッドから例外がスローされます。

    Cc488527.alert_note(ja-jp,VS.90).gifメモ :

    データ モデルでスローされる検証例外は、DynamicValidator コントロールによってキャッチされます。ページに DynamicValidator コントロールが含まれていれば、そのページにエラーを表示できます。

    partial void OnValidate(
        System.Data.Linq.ChangeAction action)
        {
            if (!Char.IsUpper(this._LastName[0]) || 
                !Char.IsUpper(this._FirstName[0]))
              throw new  ValidationException(
                 "Name must start with an uppercase letter.");
            }
    
    Private Sub OnValidate(ByVal action As _  
           System.Data.Linq.ChangeAction)
        If Not [Char].IsUpper(Me._LastName(0)) OrElse _
                Not [Char].IsUpper(Me._FirstName(0)) Then
            Throw New ValidationException( _
                "Name must start with an uppercase letter.")
        End If
    End Sub
    

使用例

この例では、RequiredAttribute 属性を使用して、Customer テーブルの Title データを検証する方法を示します。部分クラスの OnValidate メソッドを使用して、Title、FirstName、および LastName の各データ フィールドに入力された値が英大文字で始まっているかどうかを検証します。さらに、部分クラスの OnOderQtyChanging メソッドを使用して、SalesOrderDetails テーブルの OrderQty データ フィールドに入力された値が特定の最小値を超えているかどうかを確認します。

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Web.DynamicData
Imports System.ComponentModel.DataAnnotations

<MetadataType(GetType(CustomerMetadata))> _
Partial Public Class Customer


    Private Sub OnValidate(ByVal action As System.Data.Linq.ChangeAction)
        If Not Char.IsUpper(Me._LastName(0)) _
        OrElse Not Char.IsUpper(Me._FirstName(0)) _
        OrElse Not Char.IsUpper(Me._Title(0)) Then
            Throw New ValidationException( _
               "Data value must start with an uppercase letter.")
        End If
    End Sub


End Class

Public Class CustomerMetadata
    <Required()> _
    Public Title As Object

End Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.DynamicData;
using System.ComponentModel.DataAnnotations;

[MetadataType(typeof(CustomerMetadata))]
public partial class Customer
{


    partial void OnValidate(System.Data.Linq.ChangeAction action)
    {
        if (!char.IsUpper(this._LastName[0]) ||
            !char.IsUpper(this._FirstName[0])  ||
            !char.IsUpper(this._Title[0]))
            throw new ValidationException(
               "Data value must start with an uppercase letter.");
    }


}

public class CustomerMetadata
{
    [Required()]
    public object Title;

}
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Web.DynamicData
Imports System.ComponentModel.DataAnnotations

Partial Public Class SalesOrderDetail
    Private Sub OnOrderQtyChanging(ByVal value As Short)
        If value < 100 Then
            Throw New ValidationException( _
               "Quantity is less than the allowed minimum of 100.")
        End If
    End Sub
End Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.DynamicData;
using System.ComponentModel.DataAnnotations;

public partial class SalesOrderDetail
{
    partial void OnOrderQtyChanging(short value)
    {
        if (value < 100)
        {
            throw new ValidationException(
                "Quantity is less than the allowed minimum of 100.");
        }
    }
}

<%@ Page Language="VB" 
AutoEventWireup="true" CodeFile="CustomValidation.aspx.vb" 
Inherits="CustomValidation" %>


<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
    <link href="~/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
     <h2>Example: <%=Title%></h2>

     <!-- Enable dynamic behavior. The GridView must be 
     registered with the manager. See code-behind file. -->
    <asp:DynamicDataManager ID="DynamicDataManager1" runat="server"
        AutoLoadForeignKeys="true" />


    <form id="form1" runat="server">

        <!-- Capture validation exceptions -->
        <asp:DynamicValidator ID="ValidatorID" ControlToValidate="GridView1" 
            runat="server" /> 
        <asp:DynamicValidator ID="DynamicValidator1" ControlToValidate="GridView2" 
            runat="server" /> 
        <table>
            <tr>
                <td align="left" valign="top" style="font-weight:bold">
                    Customize Validation Using the Table OnValidate 
                </td>
                <td>
                    <asp:GridView ID="GridView1" 
                        runat="server" 
                        DataSourceID="GridDataSource" 
                        AutoGenerateColumns="false"  
                        AutoGenerateEditButton="true"
                        AllowPaging="true" 
                        PageSize="5"
                        AllowSorting="true">
                        <Columns>
                            <asp:DynamicField DataField="Title" />
                            <asp:DynamicField DataField="FirstName" />
                            <asp:DynamicField DataField="LastName" />
                        </Columns>
                        <EmptyDataTemplate>
                            There are currently no items in this table.
                        </EmptyDataTemplate>
                    </asp:GridView>
                </td>
            </tr>
            <tr>
                <td align="left" valign="top" style="font-weight:bold">
                    Customize Validation Using OnOrderQtyChanging
                </td>
                <td>
                    <asp:GridView ID="GridView2" 
                        runat="server" 
                        DataSourceID="GridDataSource2" 
                        AutoGenerateColumns="false"  
                        AutoGenerateEditButton="true"
                        AllowPaging="true" 
                        PageSize="5"
                        AllowSorting="true">
                        <Columns>
                            <asp:DynamicField DataField="OrderQty" />
                        </Columns>
                        <EmptyDataTemplate>
                            There are currently no items in this table.
                        </EmptyDataTemplate>
                    </asp:GridView>
                </td>
            </tr>
        </table>

    </form>

    <!-- Connect to the database -->
    <asp:LinqDataSource ID="GridDataSource" runat="server"  
         TableName="Customers" EnableUpdate="true"
        ContextTypeName="AdventureWorksLTDataContext">

    </asp:LinqDataSource>

     <!-- Connect to the database -->
    <asp:LinqDataSource ID="GridDataSource2" runat="server"  
         TableName="SalesOrderDetails" EnableUpdate="true"
        ContextTypeName="AdventureWorksLTDataContext">

    </asp:LinqDataSource>
</body>
</html>
<%@ Page Language="C#" 
AutoEventWireup="true" CodeFile="CustomValidation.aspx.cs" 
Inherits="CustomValidation" %>


<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
    <link href="~/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
     <h2>Example: <%=Title%></h2>

     <!-- Enable dynamic behavior. The GridView must be 
     registered with the manager. See code-behind file. -->
    <asp:DynamicDataManager ID="DynamicDataManager1" runat="server"
        AutoLoadForeignKeys="true" />


    <form id="form1" runat="server">

        <!-- Capture validation exceptions -->
        <asp:DynamicValidator ID="ValidatorID" ControlToValidate="GridView1" 
            runat="server" /> 
        <asp:DynamicValidator ID="DynamicValidator1" ControlToValidate="GridView2" 
            runat="server" /> 
        <table>
            <tr>
                <td align="left" valign="top" style="font-weight:bold">
                    Customize Validation Using the Table OnValidate 
                </td>
                <td>
                    <asp:GridView ID="GridView1" 
                        runat="server" 
                        DataSourceID="GridDataSource" 
                        AutoGenerateColumns="false"  
                        AutoGenerateEditButton="true"
                        AllowPaging="true" 
                        PageSize="5"
                        AllowSorting="true">
                        <Columns>
                            <asp:DynamicField DataField="Title" />
                            <asp:DynamicField DataField="FirstName" />
                            <asp:DynamicField DataField="LastName" />
                        </Columns>
                        <EmptyDataTemplate>
                            There are currently no items in this table.
                        </EmptyDataTemplate>
                    </asp:GridView>
                </td>
            </tr>
            <tr>
                <td align="left" valign="top" style="font-weight:bold">
                    Customize Validation Using OnOrderQtyChanging
                </td>
                <td>
                    <asp:GridView ID="GridView2" 
                        runat="server" 
                        DataSourceID="GridDataSource2" 
                        AutoGenerateColumns="false"  
                        AutoGenerateEditButton="true"
                        AllowPaging="true" 
                        PageSize="5"
                        AllowSorting="true">
                        <Columns>
                            <asp:DynamicField DataField="OrderQty" />
                        </Columns>
                        <EmptyDataTemplate>
                            There are currently no items in this table.
                        </EmptyDataTemplate>
                    </asp:GridView>
                </td>
            </tr>
        </table>

    </form>

    <!-- Connect to the database -->
    <asp:LinqDataSource ID="GridDataSource" runat="server"  
         TableName="Customers" EnableUpdate="true"
        ContextTypeName="AdventureWorksLTDataContext">

    </asp:LinqDataSource>

     <!-- Connect to the database -->
    <asp:LinqDataSource ID="GridDataSource2" runat="server"  
         TableName="SalesOrderDetails" EnableUpdate="true"
        ContextTypeName="AdventureWorksLTDataContext">

    </asp:LinqDataSource>
</body>
</html>
Imports System
Imports System.Collections
Imports System.Configuration
Imports System.Web.DynamicData

Partial Public Class CustomValidation
    Inherits System.Web.UI.Page
    Protected _table1 As MetaTable, _table2 As MetaTable

    Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs)
        ' Register data controls with the data manager.
        DynamicDataManager1.RegisterControl(GridView1)
        DynamicDataManager1.RegisterControl(GridView2)
    End Sub

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
        ' Get the table entities.
        _table1 = GridDataSource.GetTable()
        _table2 = GridDataSource2.GetTable()

        ' Assign title dynamically.
        Title = String.Concat("Customize Validation of the ", _
                              _table1.Name, " and ", _table2.Name, " Tables")

    End Sub
End Class
using System;
using System.Collections;
using System.Configuration;
using System.Web.DynamicData;

public partial class CustomValidation : System.Web.UI.Page
{
    protected MetaTable _table1, _table2;

    protected void Page_Init(object sender, EventArgs e)
    {
        // Register data controls with the data manager.
        DynamicDataManager1.RegisterControl(GridView1);
        DynamicDataManager1.RegisterControl(GridView2);
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        // Get the table entities.
        _table1 = GridDataSource.GetTable();
        _table2 = GridDataSource2.GetTable();

        // Assign title dynamically.
        Title = string.Concat("Customize Validation of the ",
            _table1.Name, " and ",  _table2.Name, " Tables");

    }
}

コードのコンパイル方法

このコード例をコンパイルするには、以下が必要です。

  • Microsoft Visual Studio 2008 Service Pack 1 または Visual Web Developer 2008 Express Edition Service Pack 1。

  • AdventureWorksLT サンプル データベース。SQL Server のサンプル データベースをダウンロードしてインストールする方法については、CodePlex サイトの「Microsoft SQL Server Product Samples: Database」を参照してください。実行している SQL Server のバージョン (Microsoft SQL Server 2005 または Microsoft SQL Server 2008) に対応した正しいバージョンのサンプル データベースをインストールしてください。

Dynamic Data Web サイト。これにより、カスタマイズするデータ フィールドおよびオーバーライドするメソッドを持つクラスと、データベースのデータ コンテキストを作成できます。詳細については、「Walkthrough: Creating a New Dynamic Data Web Site Using Scaffolding」を参照してください。

参照

概念

ASP.NET Dynamic Data のフィールド テンプレートの概要

ASP.NET Dynamic Data モデルの概要

ASP.NET Dynamic Data の概要

参照

RequiredAttribute

DynamicValidator

部分クラスと部分メソッド (C# プログラミング ガイド)

履歴の変更

日付

履歴

理由

2008 年 7 月

トピックを追加

SP1 機能変更