2016-08-15 2 views
0

Я получаю исключение при вызове веб-службы, которая динамически создает элементы HTML во время выполнения и возвращает отображаемые элементы в виде строки.Исключение при рендеринге динамической метки WebControl с AssociateControlID

следующая ошибка происходит на методе RenderControl() вызова:

System.Web.HttpException: Не удается найти элемент управления с идентификатором «txtCertificate», который связан с меткой «lblCertificate».

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 является обязательным для того, чтобы сделать визуализацию WebControl действительным элементом <label> и должен отображаться перед элементом управления вводом.

ответ

2

Один из способов сделать это - наследовать класс Label и заменить метод RenderBeginTag тем, что вам больше по душе. Если вы вкладываете класс этикетки он должен держать в местном контексте и остановить его утечки в остальной части приложения

Например:

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

Примечание: Вместо использования AssociatedControlId, теперь вы можете используйте обычное свойство For, которое будет делать то же самое. Также обратите внимание, как класс Label вложен внутри вашего класса страницы, поэтому он не мешает другим страницам.

К сожалению, как мы выяснили в первой версии этого ответа, если вы пытаетесь использовать .Attributes["for"] без AssociatedControlId, .NET преобразует <Label> в <span>, поэтому приведенный выше пример должен обойти это.

+0

Единственная проблема с добавлением атрибута заключается в том, что 'Label' WebControl не будет отображаться как элемент'

+0

Хм, странно, .NET меняет его на тег span, если нет связанного с ним отношения. Другим вариантом будет расширение локального веб-контроля Label, см. Мой обновленный ответ. – Delosdos

+0

. Вы находитесь на чем-то здесь, единственная проблема заключается в том, что он больше не оказывает никаких других свойств. Например, свойство 'ID' в вашем примере не отображается. – MPaul

Смежные вопросы