ASP.NET CompareValidator issue

笑着哭i 提交于 2021-02-07 11:18:20

问题


I've got a web form with Password and Confirm Password text boxes. I've got a RegularExpressionValidator attached to the first one and CompareValidator to the second one. Now the problem is when i have something in the Password field and nothing in Confirm Password field it does not display an error that fields don't match. As soon as i put something in the Confirm Password field it shows the error. I also want to allow to leave both fields blank.

I'm using .NET 2.0

What might it be?


回答1:


FWIW, if you make the Password box the ControlToValidate, and the Confirm Password box the ControlToCompare, then it will work because the password box will have something in it and hence will run the validation.

Of course, this could allow them to submit a form with an empty Password box and a filled-in Confirm box, so putting a required validator on both is probably a better idea.




回答2:


I had the exact same problem. Use a CustomValidator instead of the CompareValidator. (The CustomValidator has a helpful attribute called ValidateEmptyText, which the CompareValidator lacks, at least in ASP.NET 2.0.)

You will need to program an appropriate ServerValidate function, as well as the ClientValidationFunction. The function signature for the javascript function is basically the same as for the ServerValidate function: source (object), args (ServerValidateEventArgs).

The trickiest part is that you will need to write custom code to access the "CompareTo" textbox, since that's not part of the CustomValidator. My fields were within a FormView; you may need to adjust the code to fit your particular circumstances. In the code below, "fv" is the name of that FormView.

Client-side validation:

<script type="text/javascript">
<!--
  function cvPasswordRpt_Validate(source, args)
  {
    args.IsValid = (args.Value ==
                    document.getElementsByName("fv$tbPassword").item(0).value);
  }
//-->
</script>

ASPX Code:

<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" />

Server-side validation (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



回答3:


You also need to use a RequiredFieldValidator. A lot of the validation controls will pass if the field is empty and need to be paired in this way with RequiredFieldValidator.




回答4:


How about this?

Two TextBox fields - txtEmail1 (for email address) and txtEmail2 (for confirmation).

Attach a RegularExpressionValidator to txtEmail1 -- when blank, it won't fire. when populated, your data is validated.

Attach a CompareValidator to txtEmail1, comparing its data to txtEmail2. Then, attach a CompareValidator to txtEmail2, comparing its data to txtEmail1.

  • When both fields are blank, none of the three validators will fire.
  • When txtEmail1 is populated, it must match the regex, and it must match txtEmail2
  • When txtEmail2 is populated, it must match txtEmail1

This meets your requirement that the fields can be left blank, but fires the validation logic if either field has data.

-- joe




回答5:


CompareValidator, RegularExpressionValidator and RangeValidator validation controls are working on non-empty string values. This is useful for situations where we have an non-required field that needs to satisfy some condition when entered.

For example we have a form with two fields: primary email that must be entered; and alternative email that is not required but when entered it must be validated. To validate this we would add RequiredFieldValidator and RegularExpressionValidator to the primary email and only RegularExpressionValidator to the second field.

It would be tricky to validate mentioned form if RegularExpressionValidator was triggered on empty input, and we would have to change the regex in the second one to allow empty value which is considerably harder to do and mantain and not so obvious solution.




回答6:


I had the same problem and tried patmortech's answer which worked but causes the compare validator to show before the user types in the confirm textbox (when using client side validation) so not quite perfect.

Instead I knocked up a custom validator that only does the comparison if the Password box has something entered in it. Code below just in case it is of use to anyone else who comes across this while looking into the same issue. Use this validator with or without a required field validator on the Password box according to your requirements.

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");
    }
}



回答7:


I tried to do this: (by patmortech, many thanks!)

FWIW, if you make the Password box the ControlToValidate, and the Confirm Password box the ControlToCompare, then it will work because the password box will have something in it and hence will run the validation.

Of course, this could allow them to submit a form with an empty Password box and a filled-in Confirm box, so putting a required validator on both is probably a better idea.

to avoid leaving empty password and filled-in confirm box, I just put another compare validator on Password box with ControlToValidate and ControlToCompare values swapped.



来源:https://stackoverflow.com/questions/267872/asp-net-comparevalidator-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!