9

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

我有一个添加按钮,只需要验证子验证组,这很容易完成。保存按钮需要针对客户端和服务器端的父子验证组进行验证。我想我知道如何通过为每个组调用 Page.Validate("groupname") 方法来完成服务器端,但是如何在客户端完成呢?

4

4 回答 4

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>
于 2010-03-24T16:37:53.047 回答
4

CAbbott 的答案的问题是,在调用验证“子”组之后,不会显示“父”组中发生的验证错误。奥列格的答案更小的问题是,在“父”组准备好之前,不会对“子”组进行验证。

为了允许同时对多个组进行客户端验证,我们真正需要做的就是重写 Javascript IsValidationGroupMatch 方法,该方法确定控件是否包含在当前正在验证的集合中。

例如:

(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');" />
于 2013-08-28T12:04:37.330 回答
1

无论您采用哪种方式,都需要进行一些黑客攻击才能绕过 ASP.Net 的假设,即您不会尝试这样做。我赞成一种可重用的方法,该方法明确涉及所涉及的黑客行为。

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>";
    }
}
于 2013-01-24T10:25:47.680 回答
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>
于 2012-10-26T09:17:53.687 回答