ASP.NET CompareValidator问题

时间:2008-11-06 07:39:21

标签: asp.net validation .net-2.0 webforms

我有一个带有密码和确认密码文本框的网络表单。我有一个RegularExpressionValidator附加到第一个,CompareValidator附加到第二个。 现在的问题是,当我在密码字段中有内容而确认密码字段中没有任何内容时,它不会显示字段不匹配的错误。只要我在“确认密码”字段中输入内容,就会显示错误。 我还想允许将这两个字段留空。

我正在使用.NET 2.0

它可能是什么?

7 个答案:

答案 0 :(得分:17)

FWIW,如果您将密码框设置为ControlToValidate,并将确认密码框设置为ControlToCompare,那么它将起作用,因为密码框中将包含一些内容,因此将运行验证。

当然,这可以允许他们提交一个带有空密码框和填写确认框的表单,因此在两者上放置一个必需的验证器可能是个更好的主意。

答案 1 :(得分:6)

我遇到了完全相同的问题。使用CustomValidator而不是CompareValidator。 (CustomValidator有一个名为ValidateEmptyText的有用属性,CompareValidator缺少这个属性,至少在ASP.NET 2.0中是这样。)

您需要编写适当的ServerValidate函数以及ClientValidationFunction。 javascript函数的函数签名与ServerValidate函数基本相同:source(object),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

答案 2 :(得分:5)

您还需要使用RequiredFieldValidator。如果该字段为空并且需要以这种方式与RequiredFieldValidator配对,则会传递许多验证控件。

答案 3 :(得分:3)

这个怎么样?

两个TextBox字段 - txtEmail1(用于电子邮件地址)和txtEmail2(用于确认)。

将RegularExpressionValidator附加到txtEmail1 - 当为空白时,它不会触发。填充后,您的数据将得到验证。

将CompareValidator附加到txtEmail1,将其数据与txtEmail2进行比较。然后,将CompareValidator附加到txtEmail2,将其数据与txtEmail1进行比较。

  • 当两个字段都为空时,三个验证器都不会触发。
  • 当填充txtEmail1时,它必须与正则表达式匹配,并且必须与txtEmail2匹配
  • 填充txtEmail2时,必须与txtEmail1
  • 匹配

这符合您的要求,即字段可以留空,但如果任一字段有数据,则触发验证逻辑。

- 乔

答案 4 :(得分:0)

CompareValidator,RegularExpressionValidator和RangeValidator验证控件正在处理非空字符串值。这对于我们在输入时需要满足某些条件的非必需字段的情况非常有用。

例如,我们有一个包含两个字段的表单:必须输入的主电子邮件;以及不需要的替代电子邮件,但在输入时必须进行验证。为了验证这一点,我们将RequiredFieldValidator和RegularExpressionValidator添加到主电子邮件,并将RegularExpressionValidator添加到第二个字段。

如果在空输入上触发了RegularExpressionValidator,那么验证提到的形式会很棘手,我们将不得不在第二个中更改正则表达式以允许空值,这是相当难以做到的并且不是那么明显的解决方案。 / p>

答案 5 :(得分:0)

我遇到了同样的问题并尝试了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");
    }
}

答案 6 :(得分:0)

我试图这样做:(通过patmortech,非常感谢!)

  

FWIW,如果您将密码框设置为ControlToValidate,并将确认密码框设置为ControlToCompare,那么它将起作用,因为密码框中将包含一些内容,因此将运行验证。

     

当然,这可以允许他们提交一个带有空密码框和填写确认框的表单,因此在两者上放置一个必需的验证器可能是个更好的主意。

为了避免留下空密码和填写确认框,我只是在密码框上放了另一个比较验证器,并且控制了ControlToValidate和ControlToCompare值。