更新: 2008 年 7 月
利用 ASP.NET 动态数据,可以在数据模型中自定义和扩展数据验证。本主题介绍如何采用以下方法在数据模型中添加数据字段验证:
- 通过对各个数据字段应用动态数据 System.ComponentModel.DataAnnotations 属性来自定义这些字段的验证。这些属性用于定义常见的验证模式,例如范围检查和必填字段。利用此方法,只需编写很少的代码,就可使用预定义的验证检查。如果要对已由动态数据提供的内容应用其他验证,并且默认 System.ComponentModel.DataAnnotations 属性足以满足您的需求,则应使用此方法。 .gif) 说明: 说明:- 还可以创建自定义验证属性。这样就可以扩展由 System.ComponentModel.DataAnnotations 属性提供的验证。如果可用属性不满足特定数据字段的验证需求,则此方法很有用。有关更多信息,请参见如何:使用自定义属性在数据模型中自定义数据字段验证。 
- 通过重写处理单个数据字段的更改的分部类方法(或通过处理对应的事件)来自定义该数据字段的验证。利用此方法,可以为单个字段添加验证和业务逻辑。 
- 通过重写 OnValidate 方法(或通过处理 Validate 事件)来自定义任何数据字段的验证。当处理表中的任何数据字段时,将调用此方法。与为单个字段添加验证相比,此方法更为通用。当可以将同一个验证逻辑应用于多个数据字段时,此方法很有用。利用此方法,还可以执行涉及多个字段的验证检查。 
数据模型中引发的任何验证异常都由 DynamicValidator 控件捕捉。如果页面中包含 DynamicValidator 控件,则可以在该页面中显示错误。
- 对于添加到数据模型中的所有验证检查,都必须在数据模型中创建一个扩展表类的分部类。然后向该分部类中添加验证检查。
运行此功能的在线示例。
针对验证创建一个分部类
必须先实现一个扩展数据模型的分部类,才能在数据模型层自定义验证。这样您就可以执行以下操作:
- 通过属性添加元数据信息来自定义验证。 
- 通过实现分部类方法来自定义验证,利用这些方法,您可以创建自己的验证逻辑。 
针对验证创建分部类
- 在**“解决方案资源管理器”中,右击 App_Code 文件夹,然后单击“添加新项”**。 
- 在**“Visual Studio 已安装的模板”之下单击“类”**。 - 在**“名称”**框中,输入要添加验证的数据表的名称。 - 类名必须与表示表的实体类名匹配。例如,如果要为 Customers 表添加验证,则必须将文件命名为 Customer.cs(在 Visual C# 中)或 Customer.vb(在 Visual Basic 中),并且必须将类命名为 Customer。 
- 将 Partial 关键字(在 Visual Basic 中)或 partial 关键字(在 Visual C# 中)添加到类定义中,使它成为分部类。 - 下面的示例显示更新后的类声明。 - public partial class Customer { }- Partial Public Class Customer End Class
- 如果是在 Visual C# 中创建该类,请删除默认的构造函数。 
- 使用 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
- 在同一个文件中,创建将充当关联的元数据类的另一个类。可以将任何有效且尚未使用的名称用于该类。 - 下面的示例显示元数据类声明。 - [C#] - public class CustomerMetadata { }- Public Class CustomerMetadata End Class- 关联的元数据类提供一个可以应用验证属性的对象。 
- 将 MetadataTypeAttribute 属性应用于分部类定义。对于此属性的参数,请使用上一步中创建的关联元数据类的名称。 - 下面的示例显示已添加此属性的分部类定义。 - [MetadataType(typeof(CustomerMetadata))] public partial class Customer { }- <MetadataType(GetType(CustomerMetadata))> _ Partial Public Class Customer End Class
使用属性来自定义验证
本节演示如何使用由动态数据 System.ComponentModel.DataAnnotations 属性提供的默认验证规则来自定义验证。
使用验证属性来验证特定的数据字段
- 在元数据类中,创建一个其名称与要验证的数据字段相对应的属性或字段。 
- 对该属性 (Property) 应用 System.ComponentModel.DataAnnotations 命名空间中的属性 (Attribute) 之一。 - 下面的示例演示如何将 System.ComponentModel.DataAnnotations.RequiredAttribute 属性应用于关联的元数据类中的 Title 数据字段。如果用户输入一个空字符串,则 IsValid 方法将引发验证异常并生成错误消息。 .gif) 说明: 说明:- 通过应用 RequiredAttribute 属性,要求用户输入一个值,即使数据库本身无此要求也是如此。 - public class CustomerMetadata { [Required()] public object Title; }- Public Class CustomerMetadata <Required()> _ Public Title As Object End Class
通过使用分部类方法来自定义单个数据字段的验证
本节演示如何通过重写分部类方法来自定义验证,该方法处理对单个数据字段所做的更改。利用此类型的验证,您可以创建自己的规则来执行验证,而不依赖于在 System.ComponentModel.DataAnnotations 属性中实现的内置动态数据验证检查。
使用分部类方法验证特定的数据字段
- 重写分部类方法,该方法处理对数据字段所做的更改。 
- 添加自定义验证逻辑。 - 下面的示例演示如何在 Customer 分部类中重写 OnTitleChanging 方法。当更改 Customer 数据表的 Title 字段时,将调用此方法。示例中的代码检查用户输入的新职称是否以大写字母开头。如果数据没有通过验证,该方法将引发异常。要验证的值作为唯一参数传递给该方法。键入参数,使其与要验证的数据的数据类型匹配。 .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 属性中实现的内置动态数据验证检查。当可以将同一个验证逻辑应用于多个数据字段时,此方法很有用。利用此方法,还可以执行涉及多个字段的验证检查。
使用分部类方法来验证任何数据字段
- 重写对表中的任何数据字段进行更改时将调用的 OnValidate 分部类方法。 
- 添加自定义验证逻辑。 - 下面的示例显示如何重写 OnValidate 方法。此代码示例检查用户输入的名字和姓氏是否以大写字母开头。如果数据没有通过验证,该方法将引发异常。 .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 速成版 Service Pack 1。 
- AdventureWorksLT 示例数据库。有关如何下载和安装 SQL Server 示例数据库的信息,请参见 CodePlex 站点上的 Microsoft SQL Server Product Samples: Database(Microsoft SQL Server 产品示例:数据库)。请确保针对所运行的 SQL Server 版本(Microsoft SQL Server 2005 或 Microsoft SQL Server 2008)安装正确版本的示例数据库。 
动态数据网站。这允许您为数据库创建数据上下文,以及创建包含要自定义的数据字段和要重写的方法的类。有关更多信息,请参见 Walkthrough: Creating a New Dynamic Data Web Site Using Scaffolding。
请参见
概念
参考
修订记录
| 日期 | 修订历史记录 | 原因 | 
|---|---|---|
| 2008 年 7 月 | 新增主题。 | SP1 功能更改。 |