我有一个带有密码和确认密码文本框的网络表单。我有一个 RegularExpressionValidator 附加到第一个和 CompareValidator 到第二个。现在的问题是,当我在密码字段中有内容而在确认密码字段中没有任何内容时,它不会显示字段不匹配的错误。一旦我在“确认密码”字段中输入内容,它就会显示错误。我还想允许将两个字段都留空。
我正在使用 .NET 2.0
可能是什么?
我有一个带有密码和确认密码文本框的网络表单。我有一个 RegularExpressionValidator 附加到第一个和 CompareValidator 到第二个。现在的问题是,当我在密码字段中有内容而在确认密码字段中没有任何内容时,它不会显示字段不匹配的错误。一旦我在“确认密码”字段中输入内容,它就会显示错误。我还想允许将两个字段都留空。
我正在使用 .NET 2.0
可能是什么?
FWIW,如果您将密码框设置为 ControlToValidate,并将确认密码框设置为 ControlToCompare,那么它将起作用,因为密码框将包含某些内容,因此将运行验证。
当然,这可以让他们提交带有空密码框和已填写确认框的表单,因此在两者上都设置必需的验证器可能是一个更好的主意。
我有同样的问题。使用 CustomValidator 而不是 CompareValidator。(CustomValidator 有一个名为 ValidateEmptyText 的有用属性,CompareValidator 缺少该属性,至少在 ASP.NET 2.0 中是这样。)
您将需要编写适当的 ServerValidate 函数以及 ClientValidationFunction。javascript函数的函数签名与ServerValidate函数基本相同:source(对象),args(ServerValidateEventArgs)。
最棘手的部分是您需要编写自定义代码来访问“CompareTo”文本框,因为这不是 CustomValidator 的一部分。我的字段在 FormView 中;您可能需要调整代码以适应您的特定情况。在下面的代码中,“fv”是该 FormView 的名称。
客户端验证:
<script type="text/javascript">
<!--
function cvPasswordRpt_Validate(source, args)
{
args.IsValid = (args.Value ==
document.getElementsByName("fv$tbPassword").item(0).value);
}
//-->
</script>
ASPX 代码:
<label>New Password:</label>
<asp:TextBox ID="tbPassword" runat="server" CssClass="stdTextField"
TextMode="Password" ValidationGroup="edit" />
<br />
<label>Repeat New Password:</label>
<asp:TextBox ID="tbPasswordRpt" runat="server" CssClass="stdTextField"
TextMode="Password" ValidationGroup="edit" />
<asp:CustomValidator ID="cvPasswordRpt" runat="server" Display="Dynamic"
EnableClientScript="true" ValidationGroup="edit"
ControlToValidate="tbPasswordRpt" ValidateEmptyText="true"
ErrorMessage="Your passwords do not match."
ClientValidationFunction="cvPasswordRpt_Validate"
OnServerValidate="cvPasswordRpt_ServerValidate" />
服务器端验证(VB.NET):
Protected Sub cvPasswordRpt_ServerValidate(ByVal sender As Object,
ByVal e As ServerValidateEventArgs)
Dim _newPassword As String = DirectCast(fv.FindControl("tbPassword"),
TextBox).Text
e.IsValid = e.Value.Equals(_newPassword)
End Sub
您还需要使用RequiredFieldValidator。如果字段为空并且需要以这种方式与RequiredFieldValidator配对,则许多验证控件将通过。
这个怎么样?
两个文本框字段 - txtEmail1(用于电子邮件地址)和 txtEmail2(用于确认)。
将 RegularExpressionValidator 附加到 txtEmail1 ——当为空白时,它不会触发。填充后,您的数据将得到验证。
将 CompareValidator 附加到 txtEmail1,将其数据与 txtEmail2 进行比较。然后,将 CompareValidator 附加到 txtEmail2,将其数据与 txtEmail1 进行比较。
这符合您的要求,即字段可以留空,但如果任一字段有数据,则会触发验证逻辑。
——乔
CompareValidator、RegularExpressionValidator 和 RangeValidator 验证控件正在处理非空字符串值。这对于我们有一个非必填字段需要在输入时满足某些条件的情况很有用。
例如,我们有一个包含两个字段的表单:必须输入的主电子邮件;以及不需要但输入时必须验证的替代电子邮件。为了验证这一点,我们将RequiredFieldValidator 和RegularExpressionValidator 添加到主电子邮件,并且只将RegularExpressionValidator 添加到第二个字段。
如果在空输入上触发了 RegularExpressionValidator,那么验证上述表单会很棘手,我们必须在第二个中更改正则表达式以允许空值,这非常难做和维护,而且不是那么明显的解决方案。
我遇到了同样的问题并尝试了 patmortech 的答案,该答案有效,但导致比较验证器在用户输入确认文本框(使用客户端验证时)之前显示,因此不太完美。
相反,我敲了一个自定义验证器,它只在密码框中输入了某些内容时才进行比较。下面的代码以防万一其他人在研究同一问题时遇到此问题。根据您的要求,在密码框上使用此验证器,带或不带必填字段验证器。
public class CompareIfRequiredPasswordValidator : BaseValidator
{
private const string SCRIPTBLOCK = "UNIQUE1";
private string controlToCompare;
[Browsable(true)]
[Category("Behavior")]
[DefaultValue("")]
[IDReferenceProperty]
public string ControlToCompare
{
get { return controlToCompare; }
set { controlToCompare = value; }
}
/// <summary>
/// Server side validation function
/// </summary>
/// <returns></returns>
protected override bool EvaluateIsValid()
{
TextBox txCompare = (TextBox)FindControl(ControlToValidate);
TextBox txPassword = (TextBox)FindControl(ControlToCompare);
if (txPassword.Text.Length == 0)
{
//No password entered so don't compare
return true;
}
else
{
if (txCompare.Text == txPassword.Text)
{
return true;
}
else
{
return false;
}
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (EnableClientScript) { this.ClientScript(); }
}
//Add the custom attribute here
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
if (this.RenderUplevel)
{
Page.ClientScript.RegisterExpandoAttribute(this.ClientID, "controltocompare", base.GetControlRenderID(ControlToCompare));
}
}
//Generate and register the script for client side validation
private void ClientScript()
{
StringBuilder sb_Script = new StringBuilder();
sb_Script.Append("<script language=\"javascript\">");
sb_Script.Append("\r");
sb_Script.Append("function pw_verify(sender) {");
sb_Script.Append("\r");
sb_Script.Append("var txCompare = document.getElementById(document.getElementById(sender.id).controltovalidate);");
sb_Script.Append("\r");
sb_Script.Append("var txPassword = document.getElementById(document.getElementById(sender.id).controltocompare);");
sb_Script.Append("\r");
sb_Script.Append("if (txPassword.value == '')");
sb_Script.Append("\r");
sb_Script.Append("{");
sb_Script.Append("\r");
sb_Script.Append("return true;");
sb_Script.Append("\r");
sb_Script.Append("}");
sb_Script.Append("\r");
sb_Script.Append("else");
sb_Script.Append("\r");
sb_Script.Append("{");
sb_Script.Append("\r");
sb_Script.Append("if (txCompare.value == txPassword.value)");
sb_Script.Append("\r");
sb_Script.Append("{");
sb_Script.Append("\r");
sb_Script.Append("return true;");
sb_Script.Append("\r");
sb_Script.Append("}");
sb_Script.Append("\r");
sb_Script.Append("else");
sb_Script.Append("\r");
sb_Script.Append("{");
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("}");
sb_Script.Append("\r");
sb_Script.Append("</script>");
Page.ClientScript.RegisterClientScriptBlock(GetType(), SCRIPTBLOCK, sb_Script.ToString());
Page.ClientScript.RegisterExpandoAttribute(ClientID, "evaluationfunction", "pw_verify");
}
}
我试图这样做:(由 patmortech 提供,非常感谢!)
FWIW,如果您将密码框设置为 ControlToValidate,并将确认密码框设置为 ControlToCompare,那么它将起作用,因为密码框将包含某些内容,因此将运行验证。
当然,这可以让他们提交带有空密码框和已填写确认框的表单,因此在两者上都设置必需的验证器可能是一个更好的主意。
为了避免留下空密码和填写确认框,我只是在密码框上放置了另一个比较验证器,并交换了 ControlToValidate 和 ControlToCompare 值。