Asp.net 无法在复合控件内进行客户端验证

Asp.net 无法在复合控件内进行客户端验证,asp.net,validation,composite-controls,Asp.net,Validation,Composite Controls,我有一个自定义复合控件,它包含一个文本框、一些验证器以及几个UI组件。我根本无法让客户端验证工作。回发后,服务器端验证工作正常。我最终计划在验证失败时通过连接到验证API将自定义CSS添加到文本框中,但我甚至无法运行客户端验证 由于该控件是泛型的,所以验证器不是从复合控件本身内部生成的,而是从外部传入的,如下所示 <mycontrol:HighlightedTextbox ID="HighlightedTextbox1" runat="server" Label="test" Cs

我有一个自定义复合控件,它包含一个文本框、一些验证器以及几个UI组件。我根本无法让客户端验证工作。回发后,服务器端验证工作正常。我最终计划在验证失败时通过连接到验证API将自定义CSS添加到文本框中,但我甚至无法运行客户端验证

由于该控件是泛型的,所以验证器不是从复合控件本身内部生成的,而是从外部传入的,如下所示

    <mycontrol:HighlightedTextbox ID="HighlightedTextbox1" runat="server" Label="test" CssClass="generalText" FocusedCssClass="highlightText" ErrorCssClass="errorText">
      <validators>
        <asp:RequiredFieldValidator ID="required1" runat="server" ErrorMessage="Field is required" EnableClientScript="true" />
      </validators>
      <prompttemplate><span>this is a prompt</span></prompttemplate>
    </mycontrol:HighlightedTextbox>
我已经指定了persistchildren属性,我认为这是适当的,因此验证程序实际上被添加到了validators属性中。这似乎也很有效

    [PersistChildren(true, true), ParseChildren(true), PersistenceMode(PersistenceMode.InnerProperty)]
    public abstract class BaseHighlightedControl<TControl> : CompositeControl
      where TControl : Control
我有一个派生控件,它将一个标准文本框指定为TControl并公开一个text属性,但这实际上是派生类型所做的全部工作。复合控件依赖CreateChildControls方法来构建控件并配置验证器。这似乎应该是生命周期中的一个合适的方法,因为我已经看到了在CreateChildControls方法中创建验证器的复合控件示例

    public List<BaseValidators> Validators { get; private set; }

    /// <summary>
    /// Create the child controls
    /// </summary>
    protected override void CreateChildControls()
    {
        base.CreateChildControls();
        this.MainControl.ID = "HighlightControl";

        this.PromptTemplate.InstantiateIn(this.Prompt);
        this.Prompt.Style.Add(HtmlTextWriterStyle.Display, "inline");
        this.FieldLabel.Text = this.Label;

        if (!this.DesignMode)
        {
            this.Controls.Add(this.FieldLabel);
            this.Controls.Add(this.MainControl);
            this.Controls.Add(this.Prompt);
            AddValidators();
        }
    }

    private void AddValidators()
    {
        foreach (var validator in this.Validators.OfType<BaseValidator>())
        {
            validator.ControlToValidate = this.MainControl.ID;
            validator.ValidationGroup = this.ValidationGroup;
            validator.Display = ValidatorDisplay.Dynamic;

            this.Controls.Add(validator);
        }
    }
同样,服务器端验证也可以正常进行。javascript中的Page_Validators集合从未包含我的验证器。在我的控制之外添加到标记的任何验证器都会显示在javascript集合中,并且工作正常


我做错了什么?

问题是由于我试图在asp.net标记中创建验证程序控件,然后稍后将其传递到复合控件中。出于某种我不太理解的原因,验证器控件的生命周期似乎有点混乱,即使在复合控件将它们放在那里之前,它们从未实际添加到控件树中。其目的是在标记中创建它们,并由复合控件配置和加载。我只是使用模板系统而不是控件集合属性。这并不是我想要的,因为可以添加其他控件,但它可以完美地工作,因为这些控件现在在CreateChildControls方法中实例化。现在看起来像这样

    public ITemplate Validators { get; set; }
而不是

    public List<BaseValidators> Validators { get; private set; }

然后,我递归地遍历ValidatorContainer控件,小心避免无限递归,通过设置ControlToValidate和其他一些东西来查找我配置的验证器。

问题是由于我试图在asp.net标记中创建验证器控件,然后稍后将它们传递到复合控件中。出于某种我不太理解的原因,验证器控件的生命周期似乎有点混乱,即使在复合控件将它们放在那里之前,它们从未实际添加到控件树中。其目的是在标记中创建它们,并由复合控件配置和加载。我只是使用模板系统而不是控件集合属性。这并不是我想要的,因为可以添加其他控件,但它可以完美地工作,因为这些控件现在在CreateChildControls方法中实例化。现在看起来像这样

    public ITemplate Validators { get; set; }
而不是

    public List<BaseValidators> Validators { get; private set; }

然后,我递归地遍历ValidatorContainer控件,小心地避免无限递归,通过将控件设置为Validate等来查找我配置的验证器。

通过一些实验,我发现问题的产生是因为我试图在复合控件之外创建验证器,并将它们传递到自定义控件集合中。当我在CreateChildControls方法中简单地创建一个验证器时,它也能正常工作。通过一些实验,我发现这个问题肯定是因为我试图在复合控件之外创建验证器并将它们传递到自定义控件集合中。当我在CreateChildControls方法中创建一个验证器时,它也可以正常工作。