向 DataList 的编辑界面添加验证控件 (C#)

作者 :Scott Mitchell

下载 PDF

在本教程中,我们将了解如何轻松地将验证控件添加到 DataList 的 EditItemTemplate,以提供更万无一失的编辑用户界面。

简介

在到目前为止的 DataList 编辑教程中,DataLists 编辑界面未包含任何主动的用户输入验证,即使无效的用户输入(如缺少产品名称或负价格)会导致异常。 在 前面的教程中 ,我们了解了如何将异常处理代码添加到 DataList 事件处理程序 UpdateCommand ,以便捕获并正常显示有关引发的任何异常的信息。 但是,理想情况下,编辑界面将包含验证控件,以防止用户首先输入此类无效数据。

在本教程中,我们将了解如何轻松地将验证控件添加到 DataList, EditItemTemplate 以提供更万无一失的编辑用户界面。 具体而言,本教程采用在上一教程中创建的示例,并扩充了编辑界面以包含适当的验证。

步骤 1:复制处理 BLL 和 DAL-Level 异常中的示例

处理 BLL 和 DAL-Level 异常 教程中,我们创建了一个页面,该页面在两列可编辑的 DataList 中列出了产品的名称和价格。 本教程的目标是增强 DataList 的编辑界面,以包含验证控件。 具体而言,我们的验证逻辑将:

  • 要求提供产品名称
  • 确保为价格输入的值是有效的货币格式
  • 确保为价格输入的值大于或等于零,因为负 UnitPrice 值是非法的

在了解如何扩充前面的示例以包含验证之前,我们首先需要将示例从 ErrorHandling.aspx 文件夹中的页面 EditDeleteDataList 复制到本教程 UIValidation.aspx的页面。 为此,我们需要复制 ErrorHandling.aspx 页面 声明性标记及其源代码。 通过执行以下步骤,首先复制声明性标记:

  1. ErrorHandling.aspx Visual Studio 中打开页面
  2. 转到页面声明性标记 (单击页面底部的“源”按钮)
  3. 将 和 </asp:Content> 标记中的<asp:Content>文本 (行 3 到 32) 复制,如图 1 所示。

复制 asp:Content> 控件中的<文本

图 1:复制控件中的 <asp:Content> 文本 (单击以查看全尺寸图像)

  1. 打开 UIValidation.aspx 页面
  2. 转到页面声明性标记
  3. 粘贴控件中的 <asp:Content> 文本。

若要复制源代码,请打开页面并ErrorHandling.aspx.vb仅复制 类中的EditDeleteDataList_ErrorHandling文本。 将三个事件处理程序 (Products_EditCommandProducts_CancelCommandProducts_UpdateCommand) 与 方法一起 DisplayExceptionDetails 复制,但 不要 复制类声明或 using 语句。 将 复制的文本粘贴EditDeleteDataList_UIValidation 中的 类中 UIValidation.aspx.vb

将内容和代码从 ErrorHandling.aspxUIValidation.aspx移动到 后,请花点时间在浏览器中测试页面。 在这两个页面中,应看到相同的输出并体验相同的功能 (见图 2) 。

UIValidation.aspx页模拟 ErrorHandling.aspx 中的功能

图 2:页面 UIValidation.aspx 模拟 ErrorHandling.aspx (单击查看全尺寸图像)

步骤 2:将验证控件添加到 DataList 的 EditItemTemplate

构造数据输入表单时,用户必须输入任何必填字段,并且他们提供的所有输入都是格式正确的合法值。 为了帮助确保用户的输入有效,ASP.NET 提供了五个内置验证控件,这些控件旨在验证单个输入 Web 控件的值:

有关这五个控件的详细信息,请参阅将验证控件添加到编辑和插入接口教程,或检查 ASP.NET 快速入门教程验证控件部分

对于我们的教程,我们需要使用 RequiredFieldValidator 来确保已提供产品名称的值,并使用 CompareValidator 来确保输入的价格的值大于或等于 0,并且以有效的货币格式显示。

注意

虽然 ASP.NET 1.x 具有这五个相同的验证控件,但 ASP.NET 2.0 添加了许多改进,main两个是浏览器的客户端脚本支持,以及将页面上的验证控件分区到验证组的功能。 有关 2.0 中的新验证控件功能的详细信息,请参阅在 ASP.NET 2.0 中剖析验证控件。

首先,将必要的验证控件添加到 DataList 中 EditItemTemplate。 可以通过Designer通过单击 DataList 智能标记中的“编辑模板”链接或通过声明性语法来执行此任务。 让我们使用“设计”视图中的“编辑模板”选项逐步完成该过程。 选择编辑 DataList EditItemTemplate后,通过将 RequiredFieldValidator 从“工具箱”拖动到模板编辑界面中,将其放置在 TextBox 后面 ProductName 来添加。

将 RequiredFieldValidator 添加到“ProductName TextBox”后面的 EditItemTemplate

图 3:将 RequiredFieldValidator 添加到 EditItemTemplate AfterProductName TextBox (单击以查看全尺寸图像)

所有验证控件都通过验证单个 ASP.NET Web 控件的输入来工作。 因此,我们需要指示刚刚添加的 RequiredFieldValidator 应针对 ProductName TextBox 进行验证;这是通过将验证控件的 ControlToValidate 属性 设置为 ID 相应 Web 控件 (ProductName的 ,在此实例中) 。 接下来,将 ErrorMessage 属性 设置为 必须提供产品名称,并将 Text 属性 设置为 *。 Text属性值(如果提供)是验证失败时由验证控件显示的文本。 ErrorMessage属性值是必需的,由 ValidationSummary 控件使用;如果Text省略属性值,ErrorMessage则验证控件将在无效输入时显示该属性值。

设置 RequiredFieldValidator 的这三个属性后,屏幕应类似于图 4。

设置 RequiredFieldValidator s ControlToValidate、ErrorMessage 和 Text 属性

图 4:设置 RequiredFieldValidator 的 ControlToValidateErrorMessageText 属性 (单击以查看全尺寸图像)

将 RequiredFieldValidator 添加到 后 EditItemTemplate,剩下的就是添加产品价格 TextBox 的必要验证。 UnitPrice由于 在编辑记录时是可选的,因此无需添加 RequiredFieldValidator。 但是,我们确实需要添加 CompareValidator,以确保 UnitPrice(如果提供)格式正确设置为货币,并且大于或等于 0。

将 CompareValidator 添加到 ,EditItemTemplate并将其 属性设置为 UnitPrice,其 ErrorMessage 属性必须大于或等于零,并且不能包含货币符号,其 TextControlToValidate 属性设置为 *。 若要指示UnitPrice该值必须大于或等于 0,请将 CompareValidator 属性Operator设置为GreaterThanEqual,其 ValueToCompare 属性设置为 0,将其 Type 属性设置为 Currency

添加这两个验证控件后,DataList 的 EditItemTemplate 声明性语法应如下所示:

<EditItemTemplate>
    Product name:
        <asp:TextBox ID="ProductName" runat="server"
            Text='<%# Eval("ProductName") %>'></asp:TextBox>
        <asp:RequiredFieldValidator ID="RequiredFieldValidator1"
            ControlToValidate="ProductName"
            ErrorMessage="You must provide the product's name"
            runat="server">*</asp:RequiredFieldValidator>
    <br />
    Price:
        <asp:TextBox ID="UnitPrice" runat="server"
            Text='<%# Eval("UnitPrice", "{0:C}") %>'></asp:TextBox>
        <asp:CompareValidator ID="CompareValidator1"
            ControlToValidate="UnitPrice"
            ErrorMessage="The price must be greater than or equal to zero
                          and cannot include the currency symbol"
            Operator="GreaterThanEqual" Type="Currency" ValueToCompare="0"
            runat="server">*</asp:CompareValidator><br />
    <br />
    <asp:Button ID="UpdateProduct" runat="server" CommandName="Update"
        Text="Update" /> 
    <asp:Button ID="CancelUpdate" runat="server" CommandName="Cancel"
        Text="Cancel" />
</EditItemTemplate>

进行这些更改后,在浏览器中打开页面。 如果在编辑产品时尝试省略名称或输入无效的价格值,文本框旁边会显示一个星号。 如图 5 所示,包含货币符号(如 $19.95)的价格值被视为无效。 CompareValidator CurrencyType 允许数字分隔符 (如逗号或句点,具体取决于区域性设置) 和前导正号或减号, 但不允许货币 符号。 此行为可能会使用户感到困惑,因为编辑界面当前使用货币格式呈现 UnitPrice

输入无效的文本框旁边显示星号

图 5:输入无效的文本框旁边出现星号 (单击以查看全尺寸图像)

虽然验证按原样工作,但用户在编辑记录时必须手动删除货币符号,这是不能接受的。 此外,如果编辑界面中有无效输入,则单击“更新”和“取消”按钮都不会调用回发。 理想情况下,无论用户输入的有效性如何,“取消”按钮都会将 DataList 返回到其预编辑状态。 此外,我们需要在更新 DataList UpdateCommand 事件处理程序中的产品信息之前确保页面数据有效,因为其浏览器不支持 JavaScript 或禁用其支持的用户可以绕过验证控制客户端逻辑。

从 EditItemTemplate 的 UnitPrice TextBox 中删除货币符号

使用 CompareValidator 时 Currency``Type,要验证的输入不得包含任何货币符号。 存在此类符号会导致 CompareValidator 将输入标记为无效。 但是,我们的编辑界面当前在 TextBox 中包含 UnitPrice 货币符号,这意味着用户在保存更改之前必须显式删除货币符号。 若要解决此问题,我们有三个选项:

  1. EditItemTemplate配置 ,以便 UnitPrice TextBox 值不设置为货币格式。
  2. 允许用户输入货币符号,方法是删除 CompareValidator 并将其替换为用于检查正确设置格式的货币值的 RegularExpressionValidator。 此处的挑战是,验证货币值的正则表达式不像 CompareValidator 那样简单,如果我们想要合并区域性设置,则需要编写代码。
  3. 完全删除验证控件,并依赖于 GridView RowUpdating 事件处理程序中的自定义服务器端验证逻辑。

让我们在本教程中使用选项 1。 目前, UnitPrice 的格式设置为货币值,因为 中 TextBox EditItemTemplate的数据绑定表达式为 : <%# Eval("UnitPrice", "{0:c}") %>。 将 Eval 语句更改为 Eval("UnitPrice", "{0:n2}"),这会将结果的格式设置为精度为两位数的数字。 这可以通过声明性语法直接完成,也可以单击 DataList 中 EditItemTemplateTextBox 中的“编辑数据绑定”链接UnitPrice

通过此更改,编辑界面中的格式化价格包括逗号作为组分隔符,句点作为小数分隔符,但会忽略货币符号。

注意

从可编辑界面中删除货币格式时,我发现将货币符号作为文本放在 TextBox 之外很有帮助。 这可以提示用户无需提供货币符号。

修复“取消”按钮

默认情况下,验证 Web 控件会发出 JavaScript,以在客户端执行验证。 单击按钮、LinkButton 或 ImageButton 时,页面上的验证控件在回发之前在客户端进行检查。 如果存在任何无效数据,则取消回发。 不过,对于某些按钮,数据的有效性可能并不重要;在这种情况下,由于数据无效而取消回发是一种滋扰。

“取消”按钮就是这样一个示例。 假设用户输入了无效数据(例如省略产品名称),然后决定不想保存产品,并点击“取消”按钮。 目前,“取消”按钮会触发页面上的验证控件,该控件报告缺少产品名称并阻止回发。 用户必须仅在 TextBox 中 ProductName 键入一些文本才能取消编辑过程。

幸运的是,Button、LinkButton 和 ImageButton 有一个 CausesValidation 属性 ,该属性可以指示是否应单击 Button 启动验证逻辑 (默认为 True) 。 将“取消按钮”属性 CausesValidation 设置为 False

确保输入在 UpdateCommand 事件处理程序中有效

由于验证控件发出的客户端脚本,如果用户输入无效的输入,则验证控件将取消由 Button、LinkButton 或 ImageButton 控件启动的任何回发,这些 CausesValidation 控件的属性 True (默认) 。 但是,如果用户使用过时的浏览器或已禁用 JavaScript 支持的浏览器进行访问,则客户端验证检查将不会执行。

所有 ASP.NET 验证控件在回发时立即重复其验证逻辑,并通过 属性报告页面输入Page.IsValid的总体有效性。 但是,页面流不会根据 的值 Page.IsValid以任何方式中断或停止。 作为开发人员,我们有责任在 Page.IsValid 继续执行假定有效输入数据的代码之前,确保 属性的值 True 为 。

如果用户禁用了 JavaScript,请访问我们的页面,编辑产品,输入价格值太昂贵,然后单击“更新”按钮,将绕过客户端验证,并发生回发。 在回发时,ASP.NET 页 UpdateCommand 事件处理程序执行,并且尝试分析 太昂贵 Decimal时引发异常。 由于我们有异常处理,因此此类异常将得到正常处理,但是,如果 值为 True,则仅通过事件处理程序来UpdateCommandPage.IsValid防止无效数据从第一位置滑落。

将以下代码添加到事件处理程序的UpdateCommand开头,紧邻 块:Try

if (!Page.IsValid)
    return;

添加此内容后,仅当提交的数据有效时,才会尝试更新产品。 由于验证控制客户端脚本,大多数用户无法回发无效数据,但浏览器不支持 JavaScript 或禁用 JavaScript 支持的用户可以绕过客户端检查并提交无效数据。

注意

精明的读者会记得,使用 GridView 更新数据时,我们不需要在页面代码隐藏类中显式检查 Page.IsValid 属性。 这是因为 GridView 会为我们查询 属性, Page.IsValid 并且仅当它返回 值的 True时才继续更新。

步骤 3:汇总数据输入问题

除了五个验证控件外,ASP.NET 还包括 ValidationSummary 控件,该控件显示 ErrorMessage 检测到无效数据的验证控件的 。 此摘要数据可以作为文本显示在网页中,也可以通过模式的客户端消息框显示。 让我们来增强本教程,以包含一个客户端消息框,其中汇总了任何验证问题。

为此,请将 ValidationSummary 控件从工具箱拖到Designer。 ValidationSummary 控件的位置并不重要,因为我们要将其配置为仅将摘要显示为消息框。 添加控件后,将其 ShowSummary 属性 设置为 False ,将其 ShowMessageBox 属性 设置为 True。 添加此内容后,任何验证错误都会汇总在客户端消息框中, (请参阅图 6) 。

验证错误汇总在 Client-Side 消息框中

图 6:验证错误汇总在 Client-Side 消息框中 (单击以查看全尺寸图像)

总结

在本教程中,我们介绍了如何在尝试在更新工作流中使用用户输入之前,使用验证控件主动确保用户输入有效,从而降低出现异常的可能性。 ASP.NET 提供五个验证 Web 控件,这些控件旨在检查特定 Web 控件的输入并报告输入的有效性。 在本教程中,我们使用了 RequiredFieldValidator 和 CompareValidator 这五个控件中的两个,以确保提供产品名称,并且价格具有值大于或等于零的货币格式。

将验证控件添加到 DataList 的编辑界面非常简单,只需将它们从工具箱拖到 EditItemTemplate 上并设置少量属性即可。 默认情况下,验证控件会自动发出客户端验证脚本;他们还在回发时提供服务器端验证,将累积结果存储在 属性中 Page.IsValid 。 若要在单击 Button、LinkButton 或 ImageButton 时绕过客户端验证,请将 button s CausesValidation 属性设置为 False。 此外,在使用回发时提交的数据执行任何任务之前,请确保 属性 Page.IsValid 返回 True

到目前为止,我们检查的所有 DataList 编辑教程都有非常简单的编辑界面,其中一个 TextBox 表示产品名称,另一个用于价格。 但是,编辑界面可以包含不同 Web 控件的组合,例如 DropDownLists、Calendars、RadioButtons、CheckBoxes 等。 在下一教程中,我们将介绍如何生成使用各种 Web 控件的接口。

编程快乐!

关于作者

斯科特·米切尔是七本 ASP/ASP.NET 书籍的作者和 4GuysFromRolla.com 的创始人,自 1998 年以来一直在使用 Microsoft Web 技术。 Scott 担任独立顾问、培训师和作家。 他的最新一本书是 山姆斯在 24 小时内 ASP.NET 2.0。 可以在 上mitchell@4GuysFromRolla.com联系他,也可以通过他的博客(可在 中找到http://ScottOnWriting.NET)。

特别感谢

本教程系列由许多有用的审阅者审阅。 本教程的主要审阅者是 Dennis Patterson、Ken Pespisa 和 Liz Shulok。 有兴趣查看我即将发布的 MSDN 文章? 如果是,请在 处mitchell@4GuysFromRolla.com放置一行。