使CustomValidator与ValidationSummary messagebox一起使用的优雅方法

时间:2009-05-01 14:55:01

标签: asp.net 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的消息。有几个地方已经提出这个问题,但我没有看到一个满意的答案。

7 个答案:

答案 0 :(得分:10)

尝试在所有验证器和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
   }

更多信息:如果您不想进行ClientSide验证,请尝试使用此技巧来显示警报。对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>"); 

    }

}

答案 1 :(得分:7)

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

答案 2 :(得分:5)

我最近遇到了同样的问题。当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();
                    });
}
);

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

More details here.

答案 3 :(得分:1)

你应该写一个属性

ValidationGroup="ValidationSummary1"

在您的案例中的每个验证器。

同时检查您的网页是否有

AutoEventWireup="true"

答案 4 :(得分:1)

这对我有用:

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

答案 5 :(得分:1)

我找到了一种解决方法,用于禁用javascript并且ValidationSummary未显示errorMessage的{​​{1}}属性。这是必需的,因为如上所述,注入脚本或警报将不起作用。

添加一个新的Validator控件,我们称之为CustomValidator,将其CustomValidatorProxy属性设置为表单上的任意一个控件ControlToValidate

EnableClientScript=false事件处理程序中执行自定义验证,如果验证失败,请将ServerValidateIsValid的{​​{1}}属性设置为false,同样设置{{1}属性。

如果传递CustomValidator中的验证,请确保CustomValidatorProxy的IsValid属性设置为true。

如果ErrorMessage位于Page的ServerValidate中的CustomValidatorProxy之前,那么ServerValidate处理程序将覆盖CustomValidatorProxy所需的CustomValidator属性值返回时已经验证了ValidatorCollection值,IsValid中的CustomValidatorProxy将显示在ControlToValidate

答案 6 :(得分:1)

bduke的RegisterServerValidationMessageScript正在“伪装”,但事实并非如此。它确实解决了这个问题。每个Utility命名空间都需要此功能。