Подтвердить что ты не робот

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

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

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

Что это может быть?

4b9b3361

Ответ 1

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

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

Ответ 2

У меня была такая же проблема. Используйте 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

Ответ 3

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

Ответ 4

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

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

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

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

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

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

- joe

Ответ 5

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

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

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

Ответ 6

У меня была такая же проблема, и я попытался ответить 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");
    }
}

Ответ 7

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

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

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

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