使用AssociateControlID呈现动态标签WebControl时抛出的异常
本文关键字:异常 WebControl 标签 AssociateControlID 动态 使用 | 更新日期: 2023-09-27 18:02:26
当调用web服务时,我得到一个异常,该服务在运行时动态构建HTML元素并将呈现的元素作为字符串返回。
在RenderControl()方法调用时发生以下错误:
包含。
无法找到与标签"lblCertificate"相关联的id为"txtCertificate"的控件。StringWriter stringWriter = new StringWriter();
HtmlTextWriter writer = new HtmlTextWriter(stringWriter);
// Create System.Web.UI.WebControls.Panel (container)
Panel pnlFRow1 = new Panel();
pnlFRow1.CssClass = "f-row";
// Create System.Web.UI.WebControls.Textbox
TextBox txtCertificate = new TextBox();
txtCertificate.ID = "txtCertificate";
txtCertificate.CssClass = "f-input f-input-full";
// Create System.Web.UI.WebControls.Label
Label lblCertificate = new Label();
lblCertificate.ID = "lblCertificate";
lblCertificate.CssClass = "f-label f-label-full";
lblCertificate.AssociatedControlID = txtCertificate.ID;
lblCertificate.Text = "Certificate:";
Panel pnlCertificate = new Panel();
pnlCertificate.CssClass = "f-label f-label-full";
// Binding child controls to parent controls
pnlFRow1.Controls.Add(lblCertificate);
pnlFRow1.Controls.Add(pnlCertificate);
pnlCertificate.Controls.Add(txtCertificate);
// Render control
pnlContent.RenderControl(writer);
// Return rendered HTML
return writer.InnerWriter.ToString();
我尝试将行pnlFRow1.Controls.Add(lblCertificate);
放在行pnlCertificate.Controls.Add(txtCertificate);
之后,认为这可能是顺序重要的问题,但是这会导致相同的错误。
AssociatedControlID
属性是必须有,以便有Label
WebControl渲染作为一个实际的<label>
元素,必须在输入控件之前显示。
这样做的一种方法是继承Label类,并用您更喜欢的东西替换RenderBeginTag方法。如果你嵌套Label类,它应该保持在本地上下文中,并防止它泄漏到应用程序的其余部分
例如:public partial class _Default : Page
{
public class Label : System.Web.UI.WebControls.Label {
public string For = null;
public override void RenderBeginTag(HtmlTextWriter writer) {
AddAttributeIfExists(writer, "ID", ID);
AddAttributeIfExists(writer, "For", For);
writer.RenderBeginTag("Label");
}
private void AddAttributeIfExists(HtmlTextWriter writer, string name, string value) {
if (!string.IsNullOrWhiteSpace(value))
writer.AddAttribute(name, value);
}
}
protected void Page_Load(object sender, EventArgs e) {
StringWriter stringWriter = new StringWriter();
HtmlTextWriter writer = new HtmlTextWriter(stringWriter);
Panel test = new Panel() { ID = "PanelTest" };
TextBox txtCertificate = new TextBox() { ID = "txtCertificate" };
Label lblCertificate = new Label() { ID = "lblCertificate", Text = "Certificate", For = txtCertificate.ClientID };
test.Controls.Add(lblCertificate);
test.Controls.Add(txtCertificate);
test.RenderControl(writer);
string teststring = writer.InnerWriter.ToString();
}
}
注意:现在可以使用自定义的For
属性来代替AssociatedControlId
,它将做同样的事情。还要注意Label类是如何嵌套在页面类中的,因此它不会干扰其他页面。
不幸的是,正如我们在这个答案的第一个版本中发现的那样,如果你试图使用.Attributes["for"]
而不使用AssociatedControlId
, . net会将<Label>
转换为<span>
,所以上面的例子应该可以解决这个问题。