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

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

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

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

Спасибо, я только что обнаружил проблему, о которой даже не подозревал!

JasonS 06.11.2008 10:49
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
18
1
17 838
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

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

Спасибо за ваш ответ, Фрэнк. Пояснение к моему вопросу. Я также хочу оставить оба поля пустыми. Это означает, что я не могу использовать RequiredValidator в поле подтверждения пароля.

Muxa 06.11.2008 11:37
Ответ принят как подходящий

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

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

Красивое и простое решение ... Недурно!

reSPAWNed 06.09.2011 14:11

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

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

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

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

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

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

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

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

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

- Джо

дал бы вам еще +1, если бы мог

mrd3650 19.01.2015 18:01

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

У меня была точно такая же проблема, и этот пример позволил мне решить ее, не читая отстойную документацию на MSDN, ура!

daddywoodland 08.09.2009 14:38

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

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

Другие вопросы по теме