让 CustomValidator 与 ValidationSummary 消息框配合使用的优雅方式

发布于 2024-07-17 19:03:23 字数 1705 浏览 9 评论 0原文

我以前遇到过这个问题,但从未完全解决过。 我有一个带有多个验证器和一个 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 的消息。 这个问题已经在很多地方被问过,但我还没有看到令人满意的答案。

I have run into this problem before but never quite solved it. I have a form with several validators and also a 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" />

and on the server side:

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

My problem is: The ValidationSummary never shows the message from CustomValidator. This question has been asked in several places, but I havent seen a satisfactory answer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

白首有我共你 2024-07-24 19:03:23

尝试在所有验证器和 ValidationSummary 中使用 ValidationGroup 属性。

编辑:另一种可能性可能是服务器验证代码,

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

    }

}

Try using a ValidationGroup property across all your validators and the ValidationSummary.

EDIT: Another possibility could be the Server Validation Code

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

if CampaignRegistration.IsMemberRegistered(args.Value) is returning false, "!" is making it true and therefore making it valid. I think you should get rid of the "!" as follows:

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

UPDATE: In order for the ValidationSummary to display your custom validator message in a messagebox, you need to have ClientValidationFunction Code. If you need to display just the summary without a popup, this is not needed.

<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
   }

MORE: If you don't want to do ClientSide Validation, try this trick to show the alert. Make this change to your CustomValidator ServerValidate method:

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

    }

}
昵称有卵用 2024-07-24 19:03:23

ShowMessageBox 选项是完全客户端,因此它只会评估您是否设置了 ClientValidationFunction 位于 自定义验证器

您还可以通过注册发出警报的脚本来伪造它,因此当您从服务器验证返回时,它会提示错误消息。 这可以在 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);
            }
        }
    }

The ShowMessageBox option is fully client-side, so it will only evaluate if you have set the ClientValidationFunction on the CustomValidator.

You can also fake it by registering a script that makes an alert, so when you get back from the server's validation, it'll prompt with the error message. This can either be registered in the ServerValidate method (per @Jose Basilio), or you can call the following method during the PreRender event to register a popup with all invalid validators on the page:

    /// <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);
            }
        }
    }
与往事干杯 2024-07-24 19:03:23

我最近也遇到了同样的问题。 当 ServerValidate 声明验证失败时,ValidationSummary 未显示来自 CustomValidator 的 ErrorMessage。 由于默认情况下(正如我的小逆向工程所示)验证摘要在回发时呈现在客户端,我只是添加了一个脚本,用于检查文档加载/异步回发完成时的所有验证器,并触发为失败的验证组创建验证摘要:

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

在我的场景中我在父页面上嵌套了带有验证器、更新面板和验证摘要的用户控件。

更多详细信息请参见此处。

I've recently had same problem. ValidationSummary was not showing the ErrorMessage from CustomValidator when ServerValidate stated validation failure. Since by default (as my little reverse engineering showed) validation summary is rendered client side on postback I've simply added a script that checks all validators on document load/async postback completion and triggers validation summary creation for failed validation groups:

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

In my scenario I had nested user controls with validators, update panel and validation summary at the parent page.

More details here.

蓝海 2024-07-24 19:03:23

编写一个属性

ValidationGroup="ValidationSummary1"

您应该在您的案例中的每个验证器上

。 另请检查您的页面是否有

AutoEventWireup="true"

You should write a property

ValidationGroup="ValidationSummary1"

at every validator in your case.

Also check if your page has

AutoEventWireup="true"
眼眸里的快感 2024-07-24 19:03:23

bduke 的 RegisterServerValidationMessageScript 是“伪造的”,但事实并非如此。 它确实解决了问题。 每个实用程序命名空间都需要这个函数。

bduke's RegisterServerValidationMessageScript is "faking it", but it isn't. It really fixes the problem. Every Utility namespace needs this function somewhere.

狼亦尘 2024-07-24 19:03:23

我找到了当禁用 javascript 且 ValidationSummary 不显示 CustomValidatorerrorMessage 属性时的解决方法。 这是必需的,因为如上所述注入脚本或警报将不起作用。

添加一个新的 Validator 控件,我们将其命名为 CustomValidatorProxy,将其 ControlToValidate 属性设置为表单上的任意一个控件,并设置 EnableClientScript=false

ServerValidate 事件处理程序中执行自定义验证,如果验证失败,请设置 CustomValidatorCustomValidatorProxyIsValid 属性设置为 false 并类似地设置两个 ErrorMessage 属性。

如果通过了 ServerValidate 中的验证,请确保将 CustomValidatorProxy 的 IsValid 属性设置为 true。

如果 CustomValidatorProxy 位于页面 ValidatorCollection 中的 CustomValidator 之前,则 ServerValidate 处理程序将覆盖 IsValid 属性验证 ControlToValidate 值后 CustomValidatorProxy 将返回的值,并且来自 CustomValidatorErrorMessage 将显示在ValidationSummary

I have found a workaround for when javascript is disabled and the ValidationSummary does not show the errorMessage property of the CustomValidator. This is required as injecting script or alerts, as described above, will not work.

Add a new Validator control, let's call it CustomValidatorProxy, set its ControlToValidate property to any one of the controls on the form and EnableClientScript=false.

Within the ServerValidate event handler perform your custom validation and if validation fails set the IsValid property of the CustomValidator and CustomValidatorProxy to false and similarly set both ErrorMessage properties.

If the validation in the ServerValidate is passed ensure that the IsValid property of the CustomValidatorProxy is set to true.

Provided the CustomValidatorProxy is before the CustomValidator in the ValidatorCollection of the Page then the ServerValidate handler will override the IsValid property value that the CustomValidatorProxy would have returned having validated the ControlToValidate value and your ErrorMessage from your CustomValidator will be displayed in the ValidationSummary.

最佳男配角 2024-07-24 19:03:23

这对我有用:

<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>

This worked for me:

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文