【问题标题】:How do I get the HTML output of a UserControl in .NET (C#)?如何在 .NET (C#) 中获取 UserControl 的 HTML 输出?
【发布时间】:2010-09-22 06:01:34
【问题描述】:

如果我创建一个 UserControl 并向其中添加一些对象,我如何获取它将呈现的 HTML?

例如

UserControl myControl = new UserControl();
myControl.Controls.Add(new TextBox());

// ...something happens

return strHTMLofControl;

我只想将新建的 UserControl 转换为 HTML 字符串。

【问题讨论】:

  • 如果他的解决方案适合您,请让 azamsharp 的回答“接受”。成为一名优秀的 SO 成员 :)
  • 您还需要确保将 System.Web 添加到您的引用中,以便您可以导入 System.Web.UI(HtmlTextWriter 需要)

标签: c# html .net user-controls


【解决方案1】:

调用它的.RenderControl() 方法。

【讨论】:

    【解决方案2】:

    您可以使用Control.RenderControl(HtmlTextWriter) 呈现控件。

    StringWriter 发送到HtmlTextWriter

    StringBuilder 馈送到StringWriter

    您生成的字符串将位于 StringBuilder 对象内。

    这是此解决方案的代码示例:

    string html = String.Empty;
    using (TextWriter myTextWriter = new StringWriter(new StringBuilder()))
    {
        using (HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter))
        {
            myControl.RenderControl(myWriter);
            html = myTextWriter.ToString();
        }
    }
    

    【讨论】:

    • 您还可以将控件添加到“实时”控件集合中以避免随机异常。
    • 只需将代码示例与实际代码放在此处,就可以大大改善这个答案。
    • @theJerm:在这里?在哪里?看不到任何链接
    • StringWriter 和 HtmlTextWriter 实例未正确处理。将它们包裹在using 块中。
    【解决方案3】:

    覆盖 RenderControl 方法

    protected override void Render(HtmlTextWriter output)
    {       
       output.Write("<br>Message from Control : " + Message);       
       output.Write("Showing Custom controls created in reverse" +
                                                        "order");         
       // Render Controls.
       RenderChildren(output);
    }
    

    这将使您能够访问将写入 HTML 的编写器。

    您可能还想研究 asp.net 的自适应控制架构 adaptive control architecture of asp.net 您可以在其中“塑造”控件的默认 html 输出。

    【讨论】:

      【解决方案4】:
      //render control to string
      StringBuilder b = new StringBuilder();
      HtmlTextWriter h = new HtmlTextWriter(new StringWriter(b));
      this.LoadControl("~/path_to_control.ascx").RenderControl(h);
      string controlAsString = b.ToString();
      

      【讨论】:

      【解决方案5】:
      UserControl uc = new UserControl();
      MyCustomUserControl mu = (MyCustomUserControl)uc.LoadControl("~/Controls/MyCustomUserControl.ascx");
      
      TextWriter tw = new StringWriter();
      HtmlTextWriter hw = new HtmlTextWriter(tw);
      
      mu.RenderControl(hw);
      
      return tw.ToString();
      

      【讨论】:

      • LoadControl 解决了我的问题。 (创建新实例不起作用)
      【解决方案6】:

      晚了七年,但值得分享。

      普遍接受的解决方案 - StringBuilderStringWriterHtmlWriterRenderControl - 很好。但是有一些陷阱,不幸的是我在尝试做同样的事情时遇到了这些陷阱。如果某些控件不在Page 内,则它们会抛出错误,如果它们不在&lt;form&gt;runat="server" 内,则会抛出错误。 ScriptManager 控件展示了这两种行为。

      I eventually found a workaround here. 其要点基本上只是在编写器工作之前实例化一个新的页面和表单:

      Page page = new Page();
      page.EnableEventValidation = false;
      
      HtmlForm form = new HtmlForm();
      form.Name = "form1";
      page.Controls.Add(form1);
      
      MyControl mc = new MyControl();
      form.Controls.Add(mc);
      
      StringBuilder sb = new StringBuilder();
      StringWriter sw = new StringWriter(sb);
      HtmlTextWriter writer = new HtmlTextWriter(sw);
      
      page.RenderControl(writer);
      
      return sb.ToString();
      

      不幸的是,这为您提供了比您实际需要的更多的标记(因为它包括虚拟表单)。并且 ScriptManager 仍然会因为一些我还没有弄明白的神秘原因而失败。老实说,这很麻烦,不值得做;毕竟,在代码隐藏中生成控件的全部意义在于,您不必摆弄标记。

      【讨论】:

      • 完全正确 - 谢谢 Reikim。这些方法中困扰我的另一部分是它可能需要的实例化数量。开销的数量一直困扰着我 - 全部都是将字符串吊回浏览器。
      【解决方案7】:

      您可以使用HttpServerUtility.Execute 方法,可通过HttpContext.Current.Server.Execute 获得:

      var page = new Page();
      var myControl = (MyControl)page.LoadControl("mycontrol.ascx");
      myControl.SetSomeProperty = true;
      page.Controls.Add(myControl);
      var sw = new StringWriter();
      HttpContext.Current.Server.Execute(page, sw, preserveForm: false);
      

      这样做的好处是您还可以触发用户控件的 Page_Load 事件。

      可以在此处找到 MSDN 文档:https://msdn.microsoft.com/en-us/library/fb04e8f7(v=vs.110).aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-13
        • 2013-12-07
        • 2020-05-19
        • 2010-10-06
        相关资源
        最近更新 更多