UserControl的RenderControl要求(C#.NET)中的表单标记

我问如何呈现UserControl的HTML并使代码适用于动态生成的UserControl。

现在我正在尝试使用LoadControl加载以前生成的Control并吐出它的HTML,但它给了我这个:

必须将带有’TextBox’类型的控件放在带有runat = server的表单标记内。

我实际上并没有将控件添加到页面中,我只是想抓取它的HTML。 有任何想法吗?

这是我正在玩的一些代码:

TextWriter myTextWriter = new StringWriter(); HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter); UserControl myControl = (UserControl)LoadControl("newUserControl.ascx"); myControl.RenderControl(myWriter); return myTextWriter.ToString(); 

或者,您可以在将控件呈现为字符串的页面上禁用ServerForm / Event-validation。

以下示例说明了如何执行此操作。

 public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { string rawHtml = RenderUserControlToString(); } private string RenderUserControlToString() { UserControl myControl = (UserControl)LoadControl("WebUserControl1.ascx"); using (TextWriter myTextWriter = new StringWriter()) using (HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter)) { myControl.RenderControl(myWriter); return myTextWriter.ToString(); } } public override void VerifyRenderingInServerForm(Control control) { /* Do nothing */ } public override bool EnableEventValidation { get { return false; } set { /* Do nothing */} } } 

这是我目前使用的一个肮脏的解决方案(让它工作然后做对,对吧?)。

我已经创建了一个inheritanceUserControl类的新类,并从中创建了我创建的所有其他“UserControls”。 我将其称为formPartial(向Rails点头),这是在公共字符串renderMyHTML()方法内部:

 TextWriter myTextWriter = new StringWriter(); HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter); UserControl myDuplicate = new UserControl(); TextBox blankTextBox; foreach (Control tmpControl in this.Controls) { switch (tmpControl.GetType().ToString()) { case "System.Web.UI.LiteralControl": blankLiteral = new LiteralControl(); blankLiteral.Text = ((LiteralControl)tmpControl).Text; myDuplicate.Controls.Add(blankLiteral); break; case "System.Web.UI.WebControls.TextBox": blankTextBox = new TextBox(); blankTextBox.ID = ((TextBox)tmpControl).ID; blankTextBox.Text = ((TextBox)tmpControl).Text; myDuplicate.Controls.Add(blankTextBox); break; // ...other types of controls (ddls, checkboxes, etc.) } } myDuplicate.RenderControl(myWriter); return myTextWriter.ToString(); 

脱离我的头脑:

  1. 您需要一个包含所有可能控件(或您期望的控件)的case语句。
  2. 您需要将现有控件(文本框等)中的所有重要属性传输到新的空白控件。
  3. 没有充分利用Controls的RenderControl方法。

很容易弄乱1或2.但是,希望这可以帮助其他人提出更优雅的解决方案。

您可以将控件添加到页面,渲染html,然后从页面中删除控件。

或试试这个:

 Page tmpPage = new TempPage(); // temporary page Control tmpCtl = tmpPage.LoadControl( "~/UDynamicLogin.ascx" ); //the Form is null that's throws an exception tmpPage.Form.Controls.Add( tmpCtl ); StringBuilder html = new StringBuilder(); using ( System.IO.StringWriter swr = new System.IO.StringWriter( html ) ) { using ( HtmlTextWriter writer = new HtmlTextWriter( swr ) ) { tmpPage.RenderControl( writer ); } } 

您可以将表单添加到用户控件,也可以使用常规的html输入框

   

编辑:如果你正在尝试做一些AJAXy,也许你想要这样的东西http://aspadvice.com/blogs/ssmith/archive/2007/10/19/Render-User-Control-as-String-Template.aspx

  public static string RenderView(string path, D dataToBind) { Page pageHolder = new Page(); UserControl viewControl = (UserControl) pageHolder.LoadControl(path); if(viewControl is IRenderable) { if (dataToBind != null) { ((IRenderable) viewControl).PopulateData(dataToBind); } } pageHolder.Controls.Add(viewControl); StringWriter output = new StringWriter(); HttpContext.Current.Server.Execute(pageHolder, output, false); return output.ToString(); } 

如果不需要,您可以删除数据绑定部分。

我使用与@TcKs类似的代码遇到了同样的问题,并且无法使这些示例中的任何一个对我有用。 我通过使用UserControlLoadControl方法使其工作:

 UserControl uc = new UserControl(); Control c = uc.LoadControl("newUserControl.ascx"); c.RenderControl(myWriter);