【问题标题】:ASP.NET dynamic controls and validators - Unable to find control id '...' referenced by the 'ControlToValidate' property of '...'ASP.NET 动态控件和验证器 - 找不到由“...”的“ControlToValidate”属性引用的控件 ID“...”
【发布时间】:2011-12-01 19:20:01
【问题描述】:

我似乎有很多关于这个主题的论坛帖子/回复,但我离解决方案还差得远。

我正在将数据库中的重复数据结构加载到事件处理程序中的 UpdatePanel 控件中。重复次数会有所不同,因此所有控件都是动态创建并添加到容器面板中的。用户可以编辑数据,所以我还动态创建验证器控件 (RegularExpressionValidators)

问题在于设置验证器的 ControlToValidate 属性。无论我如何设置,我都会从服务器收到 Unable to find control id '...' referenced by the 'ControlToValidate' property of '...' 错误响应,然后由 ASP.NET AJAX JS 引发。

控件添加代码的简写如下:

TextBox licenseCode = new TextBox();
licenseCode.ID = this.getNextId();  // generated ID contains only [A-Za-Z], [0-9], :, -, .
licenseCode.MaxLength = 50;
this.purchaseEdit.Controls.Add(licenseCode);  // this.purchaseEdit is an asp:Panel

RegularExpressionValidator licenseCodeVal = new RegularExpressionValidator();
licenseCodeVal.ControlToValidate = licenseCode.ClientID;
licenseCodeVal.ID = this.getNextId();
licenseCodeVal.ValidationGroup = this.purchaseEditSave.ValidationGroup;  // save button within the panel
licenseCodeVal.ValidationExpression = @"^.{1," + licenseCode.MaxLength.ToString() + "}$";
licenseCodeVal.ErrorMessage = "Between 1 and " + licenseCode.MaxLength.ToString() + " chars.";
this.purchaseEdit.Controls.Add(licenseCodeVal);

如您所见,两个控件都添加到同一个容器中,验证器添加在 TextBox 之后,并且 ControlToValidate 属性当前设置为 TextBox 的 ClientID。 ID值我也试过了,但是不开心。

真正令人恼火的是,如果我不添加验证器,并且使用断点检查 TextBox 的 ClientID,我可以检查更新页面的 DOM 并找到 TextBox 的 ID 属性:

<input type="text" id="ctl00_ContentBody_PCTL::4890cc3a-8d07-4dee-aa9f-bdd8735fcaf8::licCode"... />

据我所知,我没有做错任何事,为什么会出现这个错误??

非常感谢任何建议。

【问题讨论】:

  • 既然你在服务器端,为什么要引用控件来验证使用它的客户端ID而不是服务器ID?
  • 正如我上面所说,我都尝试过,但都没有工作。使用服务器ID时唯一的区别是JS错误中的'missing' ID没有以ct100为前缀...

标签: asp.net updatepanel validation


【解决方案1】:

您不应使用 ClientID,而应使用 TextBox 的 ID

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.basevalidator.controltovalidate.aspx

“我也试过ID值,但不开心。”

但是你没有得到异常,只有验证不起作用?!

我的建议是将控件和验证器包装在 UserControl 中,并将其动态添加到您的容器控件中。通过这种方式,您可以使用修复 ID,因为它们都有不同的 NamingContainers

代码会更干净。封装还增加了可重用性。

【讨论】:

  • ID 而不是 ClientID 会引发相同的错误,但只是没有 ct100... 前缀。根据你的建议,我看到了你的意思,但控制 ID 用于其他领域,这意味着一个重大的变化——这本身不是一个大问题,但我真的不明白它如何解决我的问题:在这两者中我当前和您建议的场景我有一个验证器引用一个确实存在于同一容器中的 ID。
  • 您提供的信息太少。 1) getNextId() 为 ID 生成什么。显示功能。 2) 您在何时何地创建控件?您是否在 every 回发时重新创建它们,并使用与以前完全相同的相同 ID?通常,使用存储在 ViewState 变量中的计数器来获取/设置已创建控件的数量就足够了,这样您就可以在 Page_Init 或最后在 Page_Load 中重新创建它们(事件为时已晚)。
  • 感谢您的支持 :) 1) 我在上面提供了一个 ID 示例 - PCTL::4890cc3a-8d07-4dee-aa9f-bdd8735fcaf8::licCode - 使用常量前缀、后缀、分隔符和新的 GUID。 2) UpdatePanel 在单击按钮后发布,在处理程序中我获取数据库数据并循环,为每个条目创建一组控件和验证器。 ID 会更改每个帖子,但公共 ID 始终会加入 TextBox 及其验证器。您是说事件处理程序为时已晚,无法创建验证器吗?请注意,当我注释掉验证器时,我的 TextBox (从处理程序)创建得很好。
  • @tomfumb:对不起,不能坚持更久;)但请再次仔细阅读我的最后评论。我的“使用与以前完全相同的 ID 在每次回发时重新创建它们”与您的 GUID 之间有什么矛盾?!它们完全相反,在整个服务器上是唯一的,并且在每次回发时都不同。你为什么需要它们?不可能在回发时获得TextBox.Text 或处理他们的TextChanged 事件,不确定您的ControlToValidate 问题(但请确保您需要ID 而不是ClientID)。
  • 事件处理程序创建其他控件还为时不晚,但重新创建旧的动态控件为时已晚。您可以将控件添加到 Page_PreRender 并确保它们的值将存储在 ViewState 中,但 ViewState 会在 Page_Load 之前加载,因此您最迟需要在那里重新创建这些控件。
【解决方案2】:

ARGH 所以我终于想通了——它归结为 ID 中的特殊字符。我遇到了一个包含“:”的 JQuery 选择器的问题,我想我应该检查一下这是否导致了验证器问题 - 确实如此。

最后,我创建了没有任何连字符的 GUID,并将 ':' 替换为 '_',问题就消失了。 This question 帮忙。

我没有从 MSDN 中看到任何内容说某些字符不允许在 ID 中使用,但是我倾向于在进入后参考 MSDN 的具体问题,所以那里可能有一些东西。 .见下方评论

【讨论】:

  • >>我没有从 MSDN 中看到任何说某些字符不允许在 ID 中来自 MSDN Control.ID:“只有字母数字字符和下划线字符 (_) 的组合是有效的值属性。包含空格或其他无效字符将导致 ASP.NET 页面解析器错误。"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
  • 2011-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-24
相关资源
最近更新 更多