Проблема ASP.NET CompareValidator - PullRequest
       21

Проблема ASP.NET CompareValidator

18 голосов
/ 06 ноября 2008

У меня есть веб-форма с текстовыми полями Пароль и Подтверждение пароля. У меня есть RegularExpressionValidator, прикрепленный к первому, и CompareValidator ко второму. Теперь проблема в том, что когда у меня есть что-то в поле «Пароль», а в поле «Подтверждение пароля» ничего не отображается, ошибка не совпадает. Как только я помещаю что-то в поле Confirm Password, появляется сообщение об ошибке. Я также хочу разрешить оставить оба поля пустыми.

Я использую .NET 2.0

Что бы это могло быть?

Ответы [ 7 ]

17 голосов
/ 06 ноября 2008

FWIW, если вы сделаете поле Пароль ControlToValidate, а поле Подтверждение пароля - ControlToCompare, то оно будет работать, потому что в поле пароля будет что-то внутри, и, следовательно, будет выполняться проверка.

Конечно, это может позволить им отправить форму с пустым полем для пароля и заполненным полем для подтверждения, поэтому, возможно, лучше использовать требуемый валидатор для обоих вариантов.

6 голосов
/ 27 июня 2009

У меня была точно такая же проблема. Используйте CustomValidator вместо CompareValidator. (У CustomValidator есть полезный атрибут ValidateEmptyText, которого нет в CompareValidator, по крайней мере, в ASP.NET 2.0.)

Вам потребуется запрограммировать соответствующую функцию ServerValidate, а также функцию ClientValidationFunction. Подпись функции для функции javascript в основном такая же, как и для функции ServerValidate: источник (объект), аргументы (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
5 голосов
/ 06 ноября 2008

Вам также необходимо использовать RequiredFieldValidator. Многие элементы управления валидацией пройдут, если поле будет пустым и его необходимо будет выполнить таким образом с RequiredFieldValidator.

3 голосов
/ 09 марта 2009

Как насчет этого?

Два поля TextBox - txtEmail1 (для адреса электронной почты) и txtEmail2 (для подтверждения).

Присоедините RegularExpressionValidator к txtEmail1 - когда пусто, оно не сработает. после заполнения ваши данные проверяются.

Присоедините CompareValidator к txtEmail1, сравнив его данные с txtEmail2. Затем присоедините CompareValidator к txtEmail2, сравнивая его данные с txtEmail1.

  • Когда оба поля не заполнены, ни один из трех валидаторов не сработает.
  • Когда txtEmail1 заполнен, он должен соответствовать регулярному выражению и должен соответствовать txtEmail2
  • Когда заполнен txtEmail2, он должен совпадать с txtEmail1

Это соответствует вашему требованию, что поля можно оставить пустыми, но запускает логику проверки, если в любом из полей есть данные.

- Джо

0 голосов
/ 16 мая 2013

Я пытался сделать это: (от patmortech, большое спасибо!)

FWIW, если вы сделаете поле пароля ControlToValidate, а поле подтверждения пароля - ControlToCompare, то оно будет работать, потому что в поле пароля будет что-то внутри, и, следовательно, будет выполняться проверка.

Разумеется, это может позволить им отправить форму с пустым полем Пароль и заполненным полем Подтверждение, поэтому, вероятно, лучше использовать требуемый валидатор для обоих вариантов.

, чтобы не оставлять пустой пароль и заполненное поле подтверждения, я просто поместил еще один валидатор сравнения в поле Пароль с замененными значениями ControlToValidate и ControlToCompare.

0 голосов
/ 16 февраля 2012

У меня возникла та же проблема, и я попробовал ответ 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");
    }
}
0 голосов
/ 06 ноября 2008

Элементы управления проверки CompareValidator, RegularExpressionValidator и RangeValidator работают с непустыми строковыми значениями. Это полезно для ситуаций, когда у нас есть необязательное поле, которое должно удовлетворять некоторому условию при вводе.

Например, у нас есть форма с двумя полями: основной адрес электронной почты, который необходимо ввести; и альтернативный адрес электронной почты, который не требуется, но при вводе он должен быть проверен. Чтобы проверить это, мы добавили бы RequiredFieldValidator и RegularExpressionValidator к основному электронному письму и только RegularExpressionValidator во второе поле.

Было бы сложно проверить упомянутую форму, если бы RegularExpressionValidator был запущен на пустом вводе, и нам пришлось бы изменить регулярное выражение во втором, чтобы позволить пустое значение, которое значительно сложнее сделать и поддерживать, и не столь очевидное решение. 1005 *

...