我有自定义服务器控件,其中包含三个文本框。我需要使用ASP.NET字段验证器验证其内容。
我将RequiredFieldValidator的' ControlToValidate '属性设置为我的文本框的ID属性,但似乎验证程序无法找到此文本框。这是我正在尝试做的简化代码(省略当前未使用的字段和属性):
[DefaultProperty("Text")]
[ToolboxData("<{0}:ServerControl runat=server></{0}:ServerControl>")]
public class CommentServerControl : WebControl, IPostBackDataHandler
{
private TextBox _textBoxName;
private RequiredFieldValidator _requiredName;
protected override void OnInit(EventArgs e)
{
var idName = "Name-" + UniqueID;
_textBoxName = new TextBox();
_textBoxName.ID = idName;
_textBoxName.ClientIDMode = System.Web.UI.ClientIDMode.Static;
_textBoxName.ValidationGroup = ValidationGroup; // is set up via mark up
Controls.Add(_textBoxName);
_requiredName = new RequiredFieldValidator();
_requiredName.ID = "RequiredName-" + UniqueID;
_requiredName.ValidationGroup = ValidationGroup;
_requiredName.ErrorMessage = RequiredMessage; // is set up via mark up
_requiredName.ControlToValidate = _textBoxName.ID;
Controls.Add(_requiredName);
}
public string ValidationGroup
{
get
{
var s = (string)ViewState["ValidationGroup"];
return (s ?? string.Empty);
}
set
{
ViewState["ValidationGroup"] = value;
}
}
public string RequiredMessage
{
get
{
var s = (string)ViewState["RequiredMessage"];
return (s ?? string.Empty);
}
set
{
ViewState["RequiredMessage"] = value;
}
}
}
运行此代码,我收到错误'无法找到控件ID'Name-ctl00 $ MainContent $ ctl00'由'RequiredName'的'ControlToValidate'属性引用。'
我已经读过可能会发生这种情况,因为控件具有不同的NamingContainer,但在这种情况下,对NamingContainer的引用是相同的。但是, FindControl(string id)方法无法在OnInit方法中找到我的文本框控件。我究竟做错了什么?提前谢谢。
注意:使用UniqueID创建ID可用于防止多次使用我的控件时发生冲突。
答案 0 :(得分:1)
On_Init太早,因为此时尚未创建控件。
答案 1 :(得分:0)
我发现了问题所在。我不知道为什么,但控件的ID属性不能包含'$'字符。在我的例子中,UniqueID属性返回类似' ctl00 $ MainContent $ ctl00 '的字符串,因此控件的完整ID是' Name-ctl00 $ MainContent $ ctl00 '。用其他符号替换'$'(以保持唯一性)解决了这个问题。顺便说一下, FindControl 方法也开始工作了。
_textBoxName.ID = "Name_" + UniqueID.Replace('$', '_')
另请注意,符号' - '作为验证者的ID将导致JS中的语法错误(因为ASP.NET将尝试创建具有相同名称的JS对象),因此不建议使用它。