如何在 .NET (C#) 中获取 UserControl 的 HTML 输出?

Posted

技术标签:

【中文标题】如何在 .NET (C#) 中获取 UserControl 的 HTML 输出?【英文标题】:How do I get the HTML output of a UserControl in .NET (C#)? 【发布时间】: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 需要) 【参考方案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();

【讨论】:

如何把usercontrol的属性放在这里。请在此处发布***.com/questions/20491018/…【参考方案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。

【讨论】:

以上是关于如何在 .NET (C#) 中获取 UserControl 的 HTML 输出?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C# 获取已注册的 .NET 组件的位置?

如何使用 C# 在 .NET 中获取格式化的 JSON?

如何在.net core 2 c#中获取地理位置

如何从列表视图中获取数据作为字符串 C# asp.net

如何在 ASP.NET C# 中使用 foreach 获取 CheckBoxList 中选定项目的值?

如何在 c# ASP.NET 中使用 GridView_RowCommand 事件从 GridView 获取图像