ASP.Net 中的 CheckBoxList 验证 - Required Field Validator





5.00/5 (1投票)
本文介绍如何在 ASP.Net 中为 CheckBoxList Web 服务器控件使用 Required Field Validator。
引言
Microsoft .Net Framework(从 1.0 到 3.5)提供的 ASP.Net Validator 控件对开发人员来说非常有用,可以实现表单控件验证,即使是 JavaScript 知识很少的初学者也能轻松上手。然而,对于我们日常编码中迫切需要的某些控件,它缺少验证器,例如 CheckBox、CheckBoxList 等。本文介绍了如何开发自己的验证器控件来验证任何 .NET 服务器控件,并实现自定义逻辑?或者更广泛地说,如何使用自定义功能扩展 BaseValidator 类?
背景
Required Field Validators 在 .NET 验证器控件中非常受欢迎。它们在 Textbox、Dropdowns、FileUpload 等控件上都能完美工作。在编写任何 Web 表单时,例如反馈表单或注册表单,我们可能需要使用 CheckBoxList 控件让用户从列表中选择多个项目。这里有个棘手的问题。我们没有验证器...!相反,我们必须编写冗长的 JavaScript 代码来实现客户端验证,或者使用 Custom Validator 控件来实现服务器端和客户端的验证。用户还可以选择使用 Ajax 的 update panels 控件通过局部渲染页面来实现验证。然而,后一种方法很麻烦且耗时,并且完全取决于我们的主机和网络。内置的验证器不允许分配给 CheckBox 等其他控件进行验证,因为 ValidatedControlConverter 只会列出可以验证的 Web 控件。在创建自己的验证控件时,您可以启用设计器来显示支持验证控件的控件列表。
哪些控件可以被验证?
为了被验证控件引用,控件必须有一个验证属性。所有可以被验证的控件都有一个 ValidationPropertyAttribute,它指定了用于验证的属性。如果您编写自己的控件,可以通过提供这些属性之一来指定要使用的属性,从而使其参与验证。
为了使验证也能在客户端工作,此属性必须对应于在客户端呈现的 HTML 元素的 value 属性。许多复杂的控件(如 DataGrid 和 Calendar)在客户端没有 value,只能在服务器端进行验证。这就是为什么只有与 HTML 元素密切相关的控件才能参与验证。此外,控件在客户端必须具有单个逻辑值。这就是为什么 RadioButtonList 可以被验证,而 CheckBoxList 不能。
使用代码
在 .net 中,所有验证器都派生自超类 BaseValidator。因此,这是起点。所以,在编写任何供我们使用的验证器时,我们应该从 BaseValidator 派生我们的组件,以继承验证器控件的所有默认功能。
public class RequiredFieldValidatorForCheckBoxList : BaseValidator
{
//..code..
}
现在,我们必须重写下面的布尔函数来实现我们的逻辑来验证需要验证的控件。
protected override bool ControlPropertiesValid()
{
//check whether the ControlToValdate propery is set or not
if (this.ControlToValidate.Trim().Length == 0) return false;
Control ctrl = FindControl(ControlToValidate);
//check whether the right type of control is selected to validate
if ((ctrl == null) || (!(ctrl is < Type of Control to Validate, say CheckBox >))) return false; else return true;
}
下一步是通过重写布尔函数 EvaluateIsValid()(如下所示)来实现验证或无效控件的逻辑。
protected override bool EvaluateIsValid()
{
//code to implement the logic.
eg:- If the control is not checked, return true else return false.
}
下一步是在控件的 OnLoad 事件中实现,以便在控件无效或控件未正确选择时抛出异常。
protected override void OnLoad(EventArgs e)
{
if (logic == false)
{
throw new HttpException(string.Format("ControlToValidate of {0}
is either blank or not a valid CheckBoxList control", this.ID)));
}
else if{second logic == false)
{
//throw another httpexception
}
}
接下来是通过添加一个属性到表示要验证的控件的字符串属性,来启用控件在设计器中被选中列出。
[TypeConverter(typeof(ValidatedControlConverter))]
public string ControlToValidate
{
get
{
// Add code to get the ID of the control to validate.
//(should retrieve checkboxlists only)
}
set
{
// Add code to set the ID of the control to validate.
//(should set checkboxlists only)
}
}
最后一步是实现 JavaScript 来启用客户端验证。要做到这一点,您需要创建一个 StringBuilder 对象,并编写完整的 Javascript 函数来在浏览器中验证控件,并在 OnPreRender 函数中实现它。
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if((ControlPropertiesValid()) && (this.EnableClientScript))
InjectClientValidationScript();
if (this.ErrorMessage.Trim().Length == 0)
this.ErrorMessage = this.ID;
//default error message equal to the type of thecontrol
//if no error message specified while design time.
}
//code to generate clients javascript for validation
private void InjectClientValidationScript()
{
StringBuilder sb_Script = new StringBuilder();
sb_Script.Append("<script language="\""javascript\">");
sb_Script.Append("\r");
sb_Script.Append("\r");
sb_Script.Append("function validate_CBL(sender) {");
sb_Script.Append("\r");
sb_Script.Append("var val =
document.getElementById(document.getElementById
(sender.id).controltovalidate);");
sb_Script.Append("\r");
sb_Script.Append("var col =
val.getElementsByTagName(\"*\");");
sb_Script.Append("\r");
sb_Script.Append("if ( col != null ) {");
sb_Script.Append("\r");
sb_Script.Append("for ( i = 0; i < col.length; i++ ) {");
sb_Script.Append("\r");
sb_Script.Append
("if (col.item(i).tagName == \"INPUT\"){");
sb_Script.Append("\r");
sb_Script.Append("if ( col.item(i).checked ) {");
sb_Script.Append("\r");
sb_Script.Append("\r");
//sb_Script.Append("alert('true');");
sb_Script.Append("return true;");
sb_Script.Append("\r");
sb_Script.Append("}");
sb_Script.Append("\r");
sb_Script.Append("}");
sb_Script.Append("\r");
sb_Script.Append("}");
sb_Script.Append("\r");
sb_Script.Append("\r");
sb_Script.Append("\r");
sb_Script.Append("return false;");
sb_Script.Append("\r");
sb_Script.Append("}");
sb_Script.Append("\r");
sb_Script.Append("}");
sb_Script.Append("\r");
sb_Script.Append("</script>");
//Inject the script into the page
Page.ClientScript.RegisterClientScriptBlock
(GetType(), "SCRIPTBLOCK", sb_Script.ToString());
//Registering validator clientside javascript function
Page.ClientScript.RegisterExpandoAttribute
(ClientID, "evaluationfunction", "validate_CBL");
}
关注点
由于我们已从 BaseValidator 类派生了我们的组件,我们的新控件将零努力地继承父类的所有默认行为。只需要小心实现我们的逻辑使其工作。我已经开发了一个 控件(即用即取)来验证 CheckBoxList 控件。该控件的行为将与 Microsoft 的其他 Required Field Validator 控件完全相同。它内置了指定多少个复选框被勾选才能成功验证控件的功能。它有一个默认值 1,表示只需勾选一个复选框即可成功验证控件,而零表示需要勾选列表中的所有项目才能成功验证。
您可以从 http://znetcontrols.blogspot.com/2008/08/required-field-validator-for.html 下载该控件的完整功能版本。该控件已在 IE 和 FireFox 浏览器中进行了测试,并且运行良好!
参考文献
文章作者 Scott Mitchell - http://aspnet.4guysfromrolla.com/articles/092006-1.aspx
历史
上述控件已添加到我之前开发的相同控件库中,现在它包含两个控件:具有分组和记录索引的 GridView,以及用于 CheckBoxList 控件的 RequiredFieldValidator。