Элегантный способ заставить CustomValidator работать с окном сообщений ValidationSummary - PullRequest
19 голосов
/ 01 мая 2009

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

Ответы [ 7 ]

10 голосов
/ 01 мая 2009

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

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

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>"); 

    }

}
7 голосов
/ 01 мая 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);
            }
        }
    }
5 голосов
/ 06 сентября 2010

У меня недавно была такая же проблема. 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();
                    });
}
);

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

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

1 голос
/ 11 апреля 2011

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

1 голос
/ 26 октября 2010

Я нашел обходной путь, когда 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.

1 голос
/ 03 августа 2010

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

<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>
1 голос
/ 01 мая 2009

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

ValidationGroup="ValidationSummary1"

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

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

AutoEventWireup="true"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...