向 DataList 的编辑界面添加验证控件 (C#)
作者 :斯科特·米切尔
在本教程中,我们将了解将验证控件添加到 DataList 的 EditItemTemplate 是多么容易,以便提供一个更防空的编辑用户界面。
介绍
到目前为止,在 DataList 编辑教程中,DataLists 编辑界面不包含任何主动用户输入验证,即使用户输入无效(如缺少产品名称或负价格)也会导致异常。 在 前面的教程中 ,我们研究了如何将异常处理代码添加到 DataList 事件处理程序 UpdateCommand
,以便捕获和正常显示有关引发的任何异常的信息。 但是,理想情况下,编辑界面将包含验证控件,以防止用户首先输入此类无效数据。
在本教程中,我们将了解如何轻松地将验证控件添加到 DataList s EditItemTemplate
,以便提供一个更易懂的编辑用户界面。 具体而言,本教程采用在前面的教程中创建的示例,并扩充编辑界面以包含适当的验证。
步骤 1:从处理 BLL 和 DAL 级异常复制示例
在 处理 BLL 和 DAL 级异常 教程中,我们创建了一个页面,其中列出了两列可编辑 DataList 中产品的名称和价格。 本教程的目标是扩充 DataList 的编辑界面,以包含验证控件。 具体而言,验证逻辑将:
- 要求提供产品名称
- 确保为价格输入的值是有效的货币格式
- 确保为价格输入的值大于或等于零,因为负
UnitPrice
值是非法的
在查看扩充前一个示例以包含验证之前,首先需要将示例从ErrorHandling.aspx
文件夹中的页面EditDeleteDataList
复制到本教程的页面。 UIValidation.aspx
为此,我们需要复制 ErrorHandling.aspx
页面的声明性标记及其源代码。 首先通过执行以下步骤来复制声明性标记:
ErrorHandling.aspx
在 Visual Studio 中打开页面- 转到页面的声明性标记(单击页面底部的“源”按钮)
- 复制文本
<asp:Content>
和</asp:Content>
标记(第 3 至 32 行),如图 1 所示。
图 1:复制控件中的 <asp:Content>
文本(单击以查看全尺寸图像)
UIValidation.aspx
打开页面- 转到页面声明性标记
- 将文本粘贴到控件中
<asp:Content>
。
若要复制源代码,请打开ErrorHandling.aspx.vb
页面并仅复制类中的EditDeleteDataList_ErrorHandling
文本。 复制三个事件处理程序(和)和该方法,但不复制类声明或using
语句。DisplayExceptionDetails
Products_UpdateCommand
Products_CancelCommand
Products_EditCommand
将复制的文本粘贴到EditDeleteDataList_UIValidation
类中UIValidation.aspx.vb
。
在将内容和代码移 ErrorHandling.aspx
入 UIValidation.aspx
以后,花点时间在浏览器中测试页面。 在这两个页面中,应看到相同的输出并体验相同的功能(请参阅图 2)。
图 2:页面模拟功能(ErrorHandling.aspx
单击以查看全尺寸图像UIValidation.aspx
)
步骤 2:将验证控件添加到 DataList s EditItemTemplate
构造数据输入表单时,用户必须输入任何必填字段,并且提供的所有输入都是合法且格式正确的值。 为了帮助确保用户的输入有效,ASP.NET 提供了五个内置验证控件,这些控件旨在验证单个输入 Web 控件的值:
- RequiredFieldValidator 确保已提供值
- CompareValidator 针对另一个 Web 控件值或常量值验证值,或确保值的格式对于指定的数据类型是合法的
- RangeValidator 确保值在值范围内
- RegularExpressionValidator 针对 正则表达式验证值
- CustomValidator 根据自定义用户定义的方法验证值
有关这五个控件的详细信息,请参阅“将验证控件添加到编辑和插入接口”教程,或查看 ASP.NET 快速入门教程的“验证控件”部分。
在本教程中,我们需要使用 RequiredFieldValidator 来确保已提供产品名称的值和 CompareValidator,以确保输入的价格的值大于或等于 0,并且以有效的货币格式显示。
注意
尽管 ASP.NET 1.x 具有相同的五个验证控件,ASP.NET 2.0 增加了许多改进,但除了 Internet Explorer 之外,主要两项是针对浏览器的客户端脚本支持,以及将页面上的验证控件分区为验证组的功能。 有关 2.0 中的新验证控件功能的详细信息,请参阅在 ASP.NET 2.0 中剖析验证控件。
首先,将必要的验证控件添加到 DataList s EditItemTemplate
。 可以通过设计器执行此任务,方法是单击 DataList 智能标记中的“编辑模板”链接或通过声明性语法执行。 让我们使用“设计”视图中的“编辑模板”选项逐步完成该过程。 选择编辑 DataList s EditItemTemplate
后,通过将 RequiredFieldValidator 从工具箱拖动到模板编辑界面中来添加 RequiredFieldValidator,并将其放在 TextBox 之后 ProductName
。
图 3:向 TextBox 添加 RequiredFieldValidator EditItemTemplate After
ProductName
(单击以查看全尺寸图像)
所有验证控件都通过验证单个 ASP.NET Web 控件的输入来工作。 因此,我们需要指示刚添加的 RequiredFieldValidator 应针对 ProductName
TextBox 进行验证;这是通过将验证控件的属性ControlToValidate
设置为ID
适当的 Web 控件(ProductName
在此实例中)。 接下来,将属性设置为“必须提供产品名称”Text
,并将属性设置为 *。ErrorMessage
Text
属性值(如果提供)是验证控件在验证失败时显示的文本。 ErrorMessage
ValidationSummary 控件使用所需的属性值;如果Text
省略属性值,则ErrorMessage
属性值由验证控件在无效输入上显示。
设置 RequiredFieldValidator 这三个属性后,屏幕应类似于图 4。
图 4:设置 RequiredFieldValidator s ControlToValidate
ErrorMessage
和Text
属性(单击以查看全尺寸图像)
将 RequiredFieldValidator 添加到其中 EditItemTemplate
后,所有剩余项都是添加产品价格 TextBox 的必要验证。 UnitPrice
由于编辑记录时是可选的,因此无需添加 RequiredFieldValidator。 但是,我们确实需要添加 CompareValidator,以确保 UnitPrice
提供的格式正确设置为货币且大于或等于 0。
将 CompareValidator 添加到EditItemTemplate
并设置其ControlToValidate
属性,其ErrorMessage
属性UnitPrice
必须大于或等于零,并且不能包含货币符号,并且其Text
属性为 *。 若要指示UnitPrice
该值必须大于或等于 0,请将 CompareValidator s Operator
属性设置为 GreaterThanEqual
0,并将其Type
ValueToCompare
属性设置为 Currency
0。
添加这两个验证控件后,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 允许Currency
Type
数字分隔符(如逗号或句点,具体取决于区域性设置)和前导加号或减号,但不允许货币符号。 此行为可能会使用户感到困惑,因为编辑界面当前呈现 UnitPrice
使用货币格式。
图 5:星号显示在输入无效的文本框旁边(单击以查看全尺寸图像)
虽然验证按原样工作,但编辑记录时,用户必须手动删除货币符号,这是不能接受的。 此外,如果在编辑界面中没有无效的输入,则单击时,“更新”和“取消”按钮都不会调用回发。 理想情况下,无论用户输入的有效性如何,“取消”按钮都会将 DataList 返回到其预编辑状态。 此外,我们需要确保在更新 DataList UpdateCommand
事件处理程序中的产品信息之前页面数据有效,因为验证控制客户端逻辑可由浏览器不支持 JavaScript 或禁用其支持的用户绕过。
从 EditItemTemplate s UnitPrice TextBox 中删除货币符号
使用 CompareValidator s Currency``Type
时,要验证的输入不得包含任何货币符号。 存在此类符号会导致 CompareValidator 将输入标记为无效。 但是,我们的编辑界面当前在 TextBox 中包含 UnitPrice
货币符号,这意味着用户在保存更改之前必须显式删除货币符号。 若要解决此问题,我们有三个选项:
EditItemTemplate
配置以便UnitPrice
TextBox 值的格式不是货币。- 允许用户输入货币符号,方法是删除 CompareValidator 并将其替换为检查正确格式的货币值的 RegularExpressionValidator。 此处的挑战是,验证货币值的正则表达式不像 CompareValidator 那么简单,如果我们想要合并区域性设置,则需要编写代码。
- 完全删除验证控件,并依赖于 GridView
RowUpdating
事件处理程序中的自定义服务器端验证逻辑。
让我们来看看本教程的选项 1。 目前,由于 UnitPrice
TextBox 的数据绑定表达式在 : <%# Eval("UnitPrice", "{0:c}") %>
中EditItemTemplate
,格式设置为货币值。 将 Eval
语句更改为,该语句 Eval("UnitPrice", "{0:n2}")
将结果格式化为具有两位数精度的数字。 这可以通过声明性语法直接完成,也可以通过单击 DataList 中的 EditItemTemplate
TextBox 中的“编辑 DataBindings”链接UnitPrice
来完成。
通过此更改,编辑界面中的格式化价格包括逗号作为组分隔符和小数分隔符的句点,但会离开货币符号。
注意
从可编辑界面中删除货币格式时,我觉得将货币符号作为文本放在 TextBox 外部会很有帮助。 这向用户提示他们不需要提供货币符号。
修复“取消”按钮
默认情况下,验证 Web 控件发出 JavaScript 以在客户端执行验证。 单击 Button、LinkButton 或 ImageButton 时,页面上的验证控件在回发发生前在客户端进行检查。 如果有任何无效数据,则回发将被取消。 不过,对于某些按钮,数据的有效性可能并不重要;在这种情况下,由于数据无效而取消回发是一种滋扰。
“取消”按钮就是这样一个示例。 假设用户输入无效的数据,例如省略产品名称,然后决定她不想保存产品毕竟并点击“取消”按钮。 目前,“取消”按钮会触发页面上的验证控件,该控件报告缺少产品名称并阻止回发。 用户必须将某些文本 ProductName
键入到 TextBox 中,才能取消编辑过程。
幸运的是,Button、LinkButton 和 ImageButton 具有一个 CausesValidation
属性,该属性 可以指示是否单击该按钮应启动验证逻辑(默认值为 True
)。 将“取消按钮”属性 CausesValidation
设置为 False
。
确保在 UpdateCommand 事件处理程序中输入有效
由于验证控件发出的客户端脚本,如果用户输入无效输入,验证控件将取消按钮、LinkButton 或 ImageButton 控件 CausesValidation
True
启动的任何回发(默认值)。 但是,如果用户正在访问过时的浏览器或其 JavaScript 支持已被禁用的浏览器,客户端验证检查将不会执行。
所有 ASP.NET 验证控件在回发时立即重复其验证逻辑,并通过 Page.IsValid
属性报告页面输入的总体有效性。 但是,页面流不会根据值 Page.IsValid
以任何方式中断或停止。 作为开发人员,我们有责任确保在继续执行假定有效输入数据的代码之前,该 Page.IsValid
属性具有值 True
。
如果用户禁用了 JavaScript,请访问我们的页面,编辑产品,输入价格值太贵,然后单击“更新”按钮,客户端验证将被绕过,回发将随之而来。 在回发时,ASP.NET 页的 UpdateCommand
事件处理程序将执行,在尝试分析过于昂贵时 Decimal
引发异常。 由于我们有异常处理,因此此类异常将正常处理,但我们可以防止无效数据首先滑过,只需继续UpdateCommand
处理事件处理程序(如果Page.IsValid
值为)。True
将以下代码添加到事件处理程序的 UpdateCommand
开头,紧邻块之前 Try
:
if (!Page.IsValid)
return;
添加后,仅当提交的数据有效时,产品才会尝试更新。 由于验证控制客户端脚本,大多数用户将无法回发无效数据,但浏览器不支持 JavaScript 或禁用 JavaScript 的用户可以绕过客户端检查并提交无效数据。
注意
精明的读取器会回忆一下,使用 GridView 更新数据时,我们不需要显式检查 Page.IsValid
页面代码隐藏类中的属性。 这是因为 GridView 会查阅 Page.IsValid
我们的属性,并且仅在更新返回值 True
时才继续更新。
步骤 3:汇总数据输入问题
除了五个验证控件,ASP.NET 还包括 ValidationSummary 控件,该控件显示 ErrorMessage
检测到无效数据的验证控件。 此摘要数据可以显示为网页中的文本或通过模式客户端消息框显示。 让我们来增强本教程,以包含汇总任何验证问题的客户端消息框。
为此,请将 ValidationSummary 控件从工具箱拖到设计器上。 ValidationSummary 控件的位置并不重要,因为我们打算将其配置为仅将摘要显示为消息框。 添加控件后,将其ShowSummary
属性False
设置为及其ShowMessageBox
属性。True
此外,客户端消息框中汇总了任何验证错误(请参阅图 6)。
图 6:客户端消息框中汇总了验证错误(单击以查看全尺寸图像)
总结
在本教程中,我们了解了如何使用验证控件主动确保用户输入在尝试在更新工作流中使用它们之前有效,从而降低异常的可能性。 ASP.NET 提供五个验证 Web 控件,这些控件旨在检查特定 Web 控件的输入并报告输入的有效性。 在本教程中,我们使用这五个控件中的两个控制 RequiredFieldValidator 和 CompareValidator 来确保提供产品名称,并且价格的货币格式的值大于或等于零。
将验证控件添加到 DataList 的编辑界面非常简单,只需将它们拖到 EditItemTemplate
工具箱中并设置少量属性即可。 默认情况下,验证控件会自动发出客户端验证脚本;他们还在回发时提供服务器端验证,并将累积结果存储在属性中 Page.IsValid
。 若要在单击 Button、LinkButton 或 ImageButton 时绕过客户端验证,请将按钮的属性 CausesValidation
设置为 False
。 此外,在对回发提交的数据执行任何任务之前,请确保 Page.IsValid
属性返回 True
。
到目前为止,我们检查的所有 DataList 编辑教程都有非常简单的用于产品名称的 TextBox 和价格的文本框。 但是,编辑界面可以包含不同 Web 控件的组合,例如 DropDownLists、Calendars、RadioButtons、CheckBoxes 等。 在下一教程中,我们将介绍如何生成使用各种 Web 控件的接口。
快乐编程!
关于作者
斯科特·米切尔,七本 ASP/ASP.NET 书籍的作者和 4GuysFromRolla.com 的创始人,自1998年以来一直在与Microsoft Web 技术合作。 斯科特担任独立顾问、教练和作家。 他的最新书是 山姆斯在24小时内 ASP.NET 2.0。 他可以通过他的博客联系到mitchell@4GuysFromRolla.com他,可以在该博客中找到http://ScottOnWriting.NET。
特别感谢
本教程系列由许多有用的审阅者审阅。 本教程的主要审阅者是丹尼斯·帕特森、肯·佩斯皮萨和莉兹·舒洛克。 有兴趣查看即将发布的 MSDN 文章? 如果是这样,请把我扔一条线。mitchell@4GuysFromRolla.com