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

Элегантный способ заставить CustomValidator работать с почтовым ящиком ValidationSummary

Я столкнулся с этой проблемой раньше, но так и не решил. У меня есть форма с несколькими валидаторами, а также CustomValidator.

<asp:Label ID="lblMemberNum" runat="server" Text="Membership #:" CssClass="LabelMedium"  ></asp:Label>
<asp:TextBox ID="txtMemberNum" runat="server" CssClass="TextBox" ></asp:TextBox>
<asp:RequiredFieldValidator ID="rfvMemberNum" SetFocusOnError="True" runat="server"
    ControlToValidate="txtMemberNum" ErrorMessage="[ Membership # ] is required"
    CssClass="ValidationMessage" Display="Dynamic" >*</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="revMemberNum"  Display="Dynamic" runat="server" 
    ControlToValidate="txtMemberNum" CssClass="ValidationMessage" 
    ErrorMessage="[ Membership # ] can only contain letters" 
    ValidationExpression="^([a-zA-Z\d]+)$" >*</asp:RegularExpressionValidator>
<asp:CustomValidator ID="cvMemberNum" runat="server" 
    CssClass="ValidationMessage" Display="Dynamic"
    ControlToValidate="txtMemberNum" ValidateEmptyText="false"
    OnServerValidate="cvMemberNum_Validate" 
    ErrorMessage="This membership number is already registered">*</asp:CustomValidator>

<asp:ValidationSummary ID="ValidationSummary1" runat="server" 
    CssClass="ValidationMessage" 
    ShowMessageBox="True" ShowSummary="False" />

и на стороне сервера:

protected void cvMemberNum_Validate(object source, ServerValidateEventArgs args)
{
    try
    {
        args.IsValid  = (!CampaignRegistration.IsMemberRegistered(args.Value));
    }
    catch
    {
        args.IsValid = false;
    }
}

Моя проблема: ValidationSummary никогда не показывает сообщение из CustomValidator. Этот вопрос задавали в нескольких местах, но я не нашел удовлетворительного ответа.

4b9b3361

Ответ 1

Попробуйте использовать свойство ValidationGroup для всех ваших валидаторов и ValidationSummary.

РЕДАКТИРОВАТЬ: Другой возможностью может быть код проверки сервера

args.IsValid = (!CampaignRegistration.IsMemberRegistered(args.Value));

если CampaignRegistration.IsMemberRegistered(args.Value) возвращает false, "!" делает его истинным и, следовательно, делает его действительным. Я думаю, вы должны избавиться от "!" следующим образом:

args.IsValid = CampaignRegistration.IsMemberRegistered(args.Value);

UPDATE:. Чтобы ValidationSummary отображал ваше сообщение для проверки подлинности в окне сообщения, вам необходимо ClientValidationFunction Код. Если вам нужно отобразить только сводку без всплывающего окна, это не нужно.

<asp:CustomValidator ID="cvMemberNum" runat="server" 
    CssClass="ValidationMessage" Display="Dynamic"
    ControlToValidate="txtMemberNum" ValidateEmptyText="false"
    OnServerValidate="cvMemberNum_Validate"
    ClientValidationFunction = "ClientValidate"  
    ErrorMessage="This membership number is already registered">*</asp:CustomValidator>
   //JavaScript Code.
   function ClientValidate(source, args)
   {         
      args.IsValid = false; //you need to add validation logic here
   }

БОЛЬШЕ: Если вы не хотите выполнять проверку ClientSide Validation, попробуйте этот трюк, чтобы показать предупреждение. Внесите это изменение в свой метод CustomValidator ServerValidate:

protected void cvMemberNum_Validate(object source, ServerValidateEventArgs args)
{
    bool isValid = true;
    try
    {
        isValid  = (!CampaignRegistration.IsMemberRegistered(args.Value));
    }
    catch
    {
        isValid = false;
    }
    args.IsValid = isValid;

    if(!isValid)
    {
       if(!Page.IsClientScriptBlockRegistered("CustomValidation")) 
         Page.RegisterClientScriptBlock("CustomValidation", "<script>alert('This membership number is already registered');</script>"); 

    }

}

Ответ 2

Параметр ShowMessageBox полностью клиентский, поэтому он будет оценивать только если вы установили ClientValidationFunction на CustomValidator.

Вы также можете подделать его, зарегистрировав script, который делает предупреждение, поэтому, когда вы вернетесь с проверки сервера, он предложит сообщение об ошибке. Это может быть зарегистрировано в методе ServerValidate (за @Jose Basilio), или вы можете вызвать следующий метод во время события PreRender, чтобы зарегистрировать всплывающее окно со всеми недопустимыми валидаторами в страница:

    /// <summary>
    /// Registers a script to display error messages from server-side validation as the specified <see cref="UserControl"/> or <see cref="Page"/> loads from a postback.
    /// </summary>
    /// <remarks>
    /// Must be called in the PreRender if used to validate against the Text property of DNNTextEditor controls, otherwise Text will not be populated.
    /// Must set the ErrorMessage manually if using a resourcekey, otherwise the resourcekey will not have overridden the ErrorMessage property.
    /// </remarks>
    /// <param name="ctrl">The <see cref="UserControl"/> or <see cref="Page"/> which is being posted back.</param>
    /// <param name="validationGroup">The validation group against which to validate.</param>
    public static void RegisterServerValidationMessageScript(TemplateControl ctrl, string validationGroup)
    {
        if (ctrl != null && ctrl.Page.IsPostBack)
        {
            ctrl.Page.Validate(validationGroup);
            if (!ctrl.Page.IsValid)
            {
                StringBuilder errorMessage = new StringBuilder("<script language='javascript'>alert('");
                for (int i = 0; i < ctrl.Page.Validators.Count; i++)
                {
                    IValidator validator = ctrl.Page.Validators[i];
                    if (!validator.IsValid)
                    {
                        errorMessage.Append("- " + validator.ErrorMessage);
                        if (i < ctrl.Page.Validators.Count - 1)
                        {
                            errorMessage.Append(@"\r\n");
                        }
                    }
                }

                errorMessage.Append("');</script>");
                ctrl.Page.ClientScript.RegisterStartupScript(typeof(IValidator), "validationAlert", errorMessage.ToString(), false);
            }
        }
    }

Ответ 3

У меня недавно была такая же проблема. ValidationSummary не показывал ErrorMessage из CustomValidator, когда ServerValidate указал на ошибку проверки. Поскольку по умолчанию (как показала моя маленькая обратная инженерия) сводка валидации отображается на стороне клиента при обратной передаче, я просто добавил script, который проверяет все валидаторы на завершение загрузки документа /async postback и запускает сводку проверки достоверности для неудачных групп проверки:

$(document).ready(function () {
    var displayAlert = function () {
        if (typeof Page_Validators == 'undefined') return;

        var groups = [];
        for (i = 0; i < Page_Validators.length; i++)
            if (!Page_Validators[i].isvalid) {
                if (!groups[Page_Validators[i].validationGroup]) {
                    ValidationSummaryOnSubmit(Page_Validators[i].validationGroup);
                    groups[Page_Validators[i].validationGroup] = true;
                }
            }
    };

    displayAlert();

    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
                    function () {
                        displayAlert();
                    });
}
);

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

Подробнее здесь.

Ответ 4

Вы должны написать свойство

ValidationGroup="ValidationSummary1"

на каждом валидаторе в вашем случае.

Также проверьте, есть ли на вашей странице

AutoEventWireup="true"

Ответ 5

Это сработало для меня:

<asp:CustomValidator runat="server" ID="cv" 
ClientValidationFunction="ValidateFunction"
ErrorMessage="Default error
message">*</asp:CustomValidator>

<script type="text/javascript">
function ValidateFunction(sender, args) 
{

var msg ='';
var formValid = true;

[various checks setting msg and formValid]

if (msg.length > 0) { sender.errormessage = msg; }
args.IsValid = formValid;

}
</script>

Ответ 6

Я нашел обходное решение, когда javascript отключен, а ValidationSummary не показывает свойство errorMessage для CustomValidator. Это необходимо, поскольку инъекция script или предупреждения, как описано выше, не будут работать.

Добавьте новый элемент Validator, позвоните ему CustomValidatorProxy, установите его свойство ControlToValidate для любого элемента управления в форме и EnableClientScript=false.

В обработчике событий ServerValidate выполните свою собственную проверку, и если проверка не завершится, установите для свойства IsValid CustomValidator и CustomValidatorProxy значение false и аналогично установите оба свойства errorMessage.

Если проверка в ServerValidate передана, убедитесь, что для свойства IsValid для параметра CustomValidatorProxy установлено значение true.

Если CustomValidatorProxy находится перед CustomValidator в ValidatorCollection страницы, то обработчик ServerValidate переопределит значение свойства IsValid, которое вернет CustomValidatorProxy, проверив значение ControlToValidate и ваш errorMessage из вашего CustomValidator будет отображаться в ValidationSummary.

Ответ 7

bduke RegisterServerValidationMessageScript "подделка", но это не так. Это действительно исправляет проблему. Каждое пространство имен Utility нуждается в этой функции где-то.