Элегантный способ заставить 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. Этот вопрос задавался в нескольких местах, но я не видел удовлетворительного ответа.


person Alfero Chingono    schedule 01.05.2009    source источник


Ответы (7)


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

EDIT: Другой возможностью может быть код проверки сервера.

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

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

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

ОБНОВЛЕНИЕ. Чтобы в 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
   }

БОЛЬШЕ: Если вы не хотите выполнять проверку на стороне клиента, попробуйте этот трюк, чтобы показать предупреждение. Внесите это изменение в свой метод 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>"); 

    }

}
person Jose Basilio    schedule 01.05.2009
comment
Я почти уверен, что проблема не в этом. Тем не менее, я попробую это и отчитаюсь. - person Alfero Chingono; 01.05.2009
comment
Я обновил свой пост после того, как сделал наблюдение. Пожалуйста подтвердите. - person Jose Basilio; 01.05.2009
comment
Код, который вы выделили, на самом деле в порядке. Проверка не проходит, если пользователь уже зарегистрирован. Эта часть работает. Что происходит, рядом с текстовым полем появляется «*», но ValidationSummary не отображает окно сообщения. - person Alfero Chingono; 01.05.2009
comment
Если вы хотите, чтобы сводка проверки отображалась в виде окна сообщения, вам необходимо установить EnableClientScript=true для вашего CustomValidator. Пробовали ли вы вместо этого использовать ShowSummary, просто чтобы посмотреть, работает ли это? - person Jose Basilio; 01.05.2009
comment
С ShowSummary это работает. Тем не менее, я предпочитаю отображать окно сообщений и делать это через ValidationSummary. Не могу использовать пользовательский javascript. - person Alfero Chingono; 01.05.2009
comment
Это единственный способ отобразить его в окне сообщений с помощью стандартных элементов управления. Однако вы можете попробовать зарегистрировать клиентский скрипт в своем методе ServerValidate, чтобы отображалось предупреждение. - person Jose Basilio; 01.05.2009
comment
Спасибо! Думаю, это не оставляет мне другого выбора. Думал, есть способ заставить его. Я действительно ценю твою помощь. - person Alfero Chingono; 01.05.2009

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

Вы также можете подделать его, зарегистрировав скрипт, который создает предупреждение, поэтому, когда вы вернетесь с проверки сервера, он выдаст сообщение об ошибке. Это можно либо зарегистрировать в методе 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);
            }
        }
    }
person bdukes    schedule 01.05.2009
comment
Большое спасибо! Работает как шарм! - person Alfero Chingono; 01.05.2009
comment
единственная проблема в том, что на данный момент мне не разрешено отображать пользовательские js. - person Alfero Chingono; 01.05.2009

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

$(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();
                    });
}
);

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

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

person Maxim Saplin    schedule 06.09.2010

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

ValidationGroup="ValidationSummary1"

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

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

AutoEventWireup="true"
person Iralda Mitro    schedule 01.05.2009
comment
CustomValidator фактически проверяет и выполняет код на стороне сервера. Когда он недействителен, он показывает свой текст (*) рядом с текстовым полем. Однако ValidationSummary показывает другие сообщения, но не от CustomValidator. - person Alfero Chingono; 01.05.2009
comment
Просто попробуйте эти две инструкции, и скажите мне. Потому что у меня абсолютно такой же случай, и сообщение от кастомного валидатора высвечивается в валидационном сводке - person Iralda Mitro; 01.05.2009
comment
Спасибо за ответ ДаДа. Возможно, мне следует уточнить, что ValidationSummary показывает ошибку из CustomValidator, ЕСЛИ я установил ShowSummary=true. Проблема в том, что я хочу показать окно сообщений. - person Alfero Chingono; 01.05.2009

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

<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>
person Morten71    schedule 03.08.2010

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

person Super Dave    schedule 11.04.2011

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

Добавьте новый элемент управления 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.

person user487779    schedule 26.10.2010