CompositeControl中的ASP.Net CustomValidator

时间:2009-07-30 12:47:01

标签: asp.net validation composite-controls

我向你展示了一个小小的谜......以下控件的目的是每次都无法验证,无论如何,但它不会:

public class Test : CompositeControl
{
    protected override void CreateChildControls()
    {
        Controls.Clear();
        CreateControlHierachy();
        ClearChildViewState();
    }

    void CreateControlHierachy()
    {
        var validator = new CustomValidator
        {
            ErrorMessage = "Can't do that!"
        };

        validator.ServerValidate += (sender, e) =>
        {
            e.IsValid = false;
        };

        Controls.Add(validator);
    }
}

要“修复”此问题,请将以下行添加到CreateControlHierachy,并且所有内容都按预期工作:

Controls.Add(new TextBox());

该控件已在web.config中注册,并放在一个简单的页面上,如下所示:

<uc:Test runat="server" />

在回发事件上使用调试器会显示以下内容:

  • 验证器位于页面的控件层中,如预期的那样。
  • 验证器未在Page.Validators中注册。
  • Page.IsValid和validator.IsValid仍然是真的。

TextBox对验证器有什么影响以及解决此问题的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

我找到了可能的解释。 TextBox的存在为您的控件添加了一个子控件,即IPostbackDataHandler。为了加载发布数据,页面必须首先通过调用FindControl来找到控件,当然这是控件。当FindControl做它的事情时,它最终会访问你的控件的Controls集合。因为您的控件是CompositeControl,所以它调用EnsureChildControls调用CreateChildControls。

所有这些都在验证之前发生。取出TextBox并且在验证之前不再访问Controls集合,因此在验证之后才会创建验证器(很可能在预渲染期间)

由于您的验证器在验证阶段不存在,因此不会调用它。我建议在验证发生之前添加对EnsureChildControls的调用。

    protected override void OnLoad(EventArgs e)
    {
        EnsureChildControls();
        base.OnLoad(e);
    }