CompositeControl 中的 ASP.Net CustomValidator
我向您呈现一个小谜团...以下控件旨在每次都使验证失败,无论如何,但事实并非如此:
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 仍然为 true。
文本框对验证器有什么影响?解决此问题的正确方法是什么?
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:
Controls.Add(new TextBox());
The control is registered in the web.config and placed on a simple page like this:
<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.
- Both Page.IsValid and validator.IsValid are still true.
What effect is the TextBox having on the validator and what is the correct way to fix this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我为此找到了一个可能的解释。 TextBox 的存在向您的控件添加了一个子控件,该控件是 IPostbackDataHandler。 为了加载发布数据,页面必须首先找到控件,当然它是通过调用 FindControl 来找到控件的。 当 FindControl 执行其操作时,它最终会访问控件的 Controls 集合。 因为您的控件是 CompositeControl,所以它调用 EnsureChildControls,后者又调用 CreateChildControls。
所有这一切都发生在验证之前。 取出 TextBox,在验证之前不再访问 Controls 集合,因此直到验证之后才会创建验证器(很可能在预渲染期间),
因为您的验证器在验证阶段不存在,因此不会被调用。 我建议在验证发生之前添加对 EnsureChildControls 的调用。
I found a possible explanation for this. The presence of the TextBox adds a child control to your control that is an IPostbackDataHandler. In order to load the post data the page must first find the control which of course it does by calling FindControl. As FindControl does its thing it eventually accesses the Controls collection of your control. Because your control is a CompositeControl this calls EnsureChildControls which call 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)
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.