简体   繁体   English

CompositeControl中的ASP.Net CustomValidator

[英]ASP.Net CustomValidator in a CompositeControl

I present to you a little mystery... the following control is intended to fail validation every time, no matter what, but it does not: 我给您带来一个小谜团...以下控件旨在使验证每次都失败,无论如何,但并非如此:

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

To "fix" the issue, add the following line to CreateControlHierachyand all works as expected: 要“解决”该问题,请将以下行添加到CreateControlHierachy,然后按预期完成所有操作:

Controls.Add(new TextBox());

The control is registered in the web.config and placed on a simple page like this: 该控件已在web.config中注册,并放置在一个简单的页面上,如下所示:

<uc:Test runat="server" />

Using the debugger on a post back event reveals the following: 在回发事件上使用调试器将显示以下内容:

  • The validator is in the control hierachy on the page, as expected. 验证程序位于页面上的控件层次结构中,符合预期。
  • The validator is not registered in Page.Validators. 验证器未在Page.Validators中注册。
  • Both Page.IsValid and validator.IsValid are still true. Page.IsValid和validator.IsValid都仍然为true。

What effect is the TextBox having on the validator and what is the correct way to fix this? TextBox对验证器有什么影响?解决此问题的正确方法是什么?

I found a possible explanation for this. 我为此找到了可能的解释。 The presence of the TextBox adds a child control to your control that is an IPostbackDataHandler. TextBox的存在将一个子控件添加到您的IPostbackDataHandler控件中。 In order to load the post data the page must first find the control which of course it does by calling FindControl. 为了加载发布数据,页面必须首先通过调用FindControl查找控件,该控件当然要执行此操作。 As FindControl does its thing it eventually accesses the Controls collection of your control. 当FindControl执行其操作时,它最终将访问控件的Controls集合。 Because your control is a CompositeControl this calls EnsureChildControls which call CreateChildControls. 因为您的控件是CompositeControl,所以此方法将调用确保儿童控件,后者将调用CreateChildControls。

All of this happens before Validation. 所有这些都发生在验证之前。 Take out the TextBox and the Controls collection is no longer accessed before validation and therefore the validator is not created until after validation (most likely during prerender) 取出TextBox,然后在验证之前不再访问Controls集合,因此直到验证之后才创建验证器(很可能在预渲染期间)

Since your validator doesn't exist at the validation stage it doesn't get called. 由于您的验证程序在验证阶段不存在,因此不会被调用。 I recommend adding a call to EnsureChildControls before validation occurs. 我建议在验证之前添加对确保儿童控件的调用。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM