如何验证多个验证组?

时间:2010-03-24 16:18:29

标签: asp.net validation validationgroup

我有两个验证组:父母和孩子

我有一个添加按钮,只需要验证子验证组就可以轻松完成。保存按钮需要针对父和子验证组(客户端和服务器端)进行验证。我想我知道如何通过为每个组调用Page.Validate(“groupname”)方法来实现服务器端,但是如何在客户端完成呢?

4 个答案:

答案 0 :(得分:13)

你应该能够通过创建一个使用Page_ClientValidate然后让按钮调用该函数的javascript函数来实现这一目标

<asp:Button ID="btnSave" Text="Save" OnClientClick="return validate()" runat="server" />

<script type="text/javascript">
    function validate() {
        var t1 = Page_ClientValidate("parent");
        var t2 = Page_ClientValidate("child");

        if (!t1 || !t2) return false;

        return true;
    }
</script>

答案 1 :(得分:4)

CAbbott的答案问题是,在调用验证“子”组后,“父”组中发生的验证错误将不会显示。 Oleg回答的一个小问题是,在“父”组准备就绪之前,“子”组的验证不会发生。

我们真正需要做的是同时允许多个组的客户端验证是覆盖Javascript IsValidationGroupMatch方法,该方法确定控件是否包含在要验证的当前集中。 / p>

例如:

(function replaceValidationGroupMatch() {

    // If this is true, IsValidationGroupMatch doesn't exist - oddness is afoot!
    if (!IsValidationGroupMatch) throw "WHAT? IsValidationGroupmatch not found!";

    // Replace ASP.net's IsValidationGroupMatch method with our own...
    IsValidationGroupMatch = function(control, validationGroup) {
        if (!validationGroup) return true;

        var controlGroup = '';
        if (typeof(control.validationGroup) === 'string') controlGroup = control.validationGroup;

        // Deal with potential multiple space-delimited groups being validated
        var validatingGroups = validationGroup.split(' ');

        for (var i = 0; i < validatingGroups.length; i++) {
            if (validatingGroups[i] === controlGroup) return true;
        }

        // Control's group not in any being validated, return false
        return false;
    };
} ());

// You can now validate against multiple groups at once, for example:
// space-delimited list.  This would validate against the Decline group:
//
//  Page_ClientValidate('Decline');
//
// while this would validate against the Decline, Open and Complete groups:
//
//  Page_ClientValidate('Open Decline Complete');
//
// so if you wanted to validate all three upon click of a button, you'd do:

<asp:Button ID="yourButton" runat="server" 
    OnClick="ButtonSave_Click" CausesValidation="false" 
    OnClientClick="return Page_ClientValidate('Open Decline Complete');" />

答案 2 :(得分:1)

如果您两次调用Page_ClientValidate(..),则只会显示最后一个验证结果,而第一个验证结果可能没问题。因此,只有第一次调用返回true时才应进行第二次调用

<script type="text/javascript">
    var parentOk= Page_ClientValidate('parent');
    var childOk = false;
    if (parentOk) {
        childOk = Page_ClientValidate('child');
    }

    return parentOk && childOk;
</script>

答案 3 :(得分:1)

无论你做什么,都需要一些黑客来绕过ASP.Net的假设,你不会尝试这样做。我赞成一种可重复使用的方法,该方法明确涉及所涉及的hackery。

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebSandbox.Validators
{
    /// <summary>
    ///   <para>
    ///     Validates a different validation group. Among the use cases envisioned are
    ///     <list type="">
    ///       <item>
    ///         Validating one set of rules when the user clicks "Save draft" and validating those rules plus some
    ///         extra consistency checks when they click "Send".
    ///       </item>
    ///       <item>
    ///         Grouping controls in a <code>fieldset</code> into a validation group with a
    ///         <code>ValidationSummary</code> and then having a final <code>ValidationSummary</code> which tells the
    ///         user which groups still have errors.
    ///       </item>
    ///     </list>
    ///   </para>
    ///   <para>
    ///     We include checks against setting <code>GroupToValidate</code> to the same value as
    ///     <code>ValidationGroup</code>, but we don't yet include checks for infinite recursion with one validator
    ///     in group A which validates group B and another in group B which validates group A. Caveat utilitor.
    ///   </para>
    /// </summary>
    public class ValidationGroupValidator : BaseValidator
    {
        public string GroupToValidate
        {
            get { return ViewState["G2V"] as string; }
            set { ViewState["G2V"] = value; }
        }

        protected override bool ControlPropertiesValid()
        {
            if (string.IsNullOrEmpty(GroupToValidate)) throw new HttpException("GroupToValidate not specified");
            if (GroupToValidate == ValidationGroup) throw new HttpException("Circular dependency");
            // Don't call the base, because we don't want a "control to validate"
            return true;
        }

        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            base.AddAttributesToRender(writer);

            writer.AddAttribute("evaluationfunction", "ValidateValidationGroup");
            writer.AddAttribute("GroupToValidate", GroupToValidate);
        }

        protected override void OnPreRender(EventArgs e)
        {
            // The standard validation JavaScript is too restrictive for this validator to work, so we have to replace a key function.
            // Fortunately this runs later than the standard JS, so we can simply overwrite the existing value of Page_ClientValidate.
            Page.ClientScript.RegisterStartupScript(typeof(ValidationGroupValidator), "validationJS", _ValidationJS);

            base.OnPreRender(e);
        }

        protected override bool EvaluateIsValid()
        {
            if (string.IsNullOrEmpty(GroupToValidate)) return false;

            bool groupValid = true;
            foreach (IValidator validator in Page.GetValidators(GroupToValidate))
            {
                validator.Validate();
                groupValid &= validator.IsValid;
            }

            return groupValid;
        }

        private const string _ValidationJS = @"<script type=""text/javascript"">
function ValidateValidationGroup(val) {
    if (typeof(val.GroupToValidate) == ""string"") {
        val.valid = PageMod_DoValidation(val.GroupToValidate);
    }
}

function Page_ClientValidate(validationGroup) {
    Page_InvalidControlToBeFocused = null;
    if (!Page_Validators) return true;

    var i, ctrl;

    // Mark everything as valid.
    for (i = 0; i &lt; Page_Validators.length; i++) {
        Page_Validators[i].finalValid = true;
    }
    if (Page_ValidationSummaries) {
        for (i = 0; i &lt; Page_ValidationSummaries.length; i++) {
            Page_ValidationSummaries[i].finalDisplay = ""none"";
        }
    }

    // Validate.
    var groupValid = PageMod_DoValidation(validationGroup);

    // Update displays once.
    for (i = 0; i &lt; Page_Validators.length; i++) {
        ctrl = Page_Validators[i];
        ctrl.isvalid = ctrl.finalValid;
        ValidatorUpdateDisplay(ctrl);
    }
    if (Page_ValidationSummaries) {
        for (i = 0; i &lt; Page_ValidationSummaries.length; i++) {
            ctrl = Page_ValidationSummaries[i];
            ctrl.style.display = ctrl.finalDisplay;
        }
    }

    ValidatorUpdateIsValid();
    Page_BlockSubmit = !Page_IsValid;
    return Page_IsValid;
}

function PageMod_DoValidation(validationGroup) {
    var groupValid = true, validator, i;
    for (i = 0; i &lt; Page_Validators.length; i++) {
        validator = Page_Validators[i];
        ValidatorValidate(validator, validationGroup, null);
        validator.finalValid &amp;= validator.isvalid;
        groupValid &amp;= validator.isvalid;
    }

    if (Page_ValidationSummaries) {
        ValidationSummaryOnSubmit(validationGroup, groupValid);

        var summary;
        for (i = 0; i &lt; Page_ValidationSummaries.length; i++) {
            summary = Page_ValidationSummaries[i];
            if (summary.style.display !== ""none"") summary.finalDisplay = summary.style.display;
        }
    }

    return groupValid;
}
</script>";
    }
}