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

50
如果我创建一个UserControl并向其中添加一些对象,那么该如何获取它将呈现的HTML?
例如。
例如。
UserControl myControl = new UserControl();
myControl.Controls.Add(new TextBox());

// ...something happens

return strHTMLofControl;

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


2
如果azamsharp的解决方案对您有用,请将其答案标记为“已接受”。成为一个好的SO社区成员 :) - Sunny Milenov
您还需要确保将System.Web添加到您的引用中,以便您可以导入System.Web.UI(HtmlTextWriter所需的内容)。 - sacredfaith
7个回答

56

您可以使用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();
    }
}

1
你也可以将控件添加到“实时”控件集合中,以避免随机异常。 - Atanas Korchev
23
将代码示例与实际代码一起放在这里,可以极大地改善此答案。 - theJerm
@theJerm:在哪里?我看不到任何链接。 - Jitendra Pancholi
StringWriter和HtmlTextWriter实例没有被正确处理。请将它们包装在using块中以进行处理。 - Kon

32
//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();

如何在此处放置用户控件的属性。请在此处发布:http://stackoverflow.com/questions/20491018/error-executing-child-request-for-handler-system-web-ui-page-while-convertin - Rajaram Shelar

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

4
LoadControl 解决了我的问题。(创建新实例无法解决) - BrunoLM

7

虽然晚了七年,但这个内容值得分享。

通常被接受的解决方案是将StringBuilder转换为StringWriter再转换为HtmlWriter最后转换为RenderControl。但是还有一些需要注意的地方,我在尝试做同样的事情时不幸遇到了一些问题。如果某些控件不在Page内部,它们会抛出错误;如果某些控件没有带有runat="server"<form>,它们也会抛出错误。ScriptManager控件表现出了这两种行为。

我最终在这里找到了一个解决方法。其要点就是在进行编写工作之前实例化一个新的PageForm

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。这些方法的另一个令我困扰的部分是它可能需要的实例化数量。这种开销让我感到不安 - 所有这些只为了将一个字符串传回浏览器。 - Michael

4

重写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输出。

1
调用它的.RenderControl()方法。

1
你可以使用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/zh-cn/library/fb04e8f7(v=vs.110).aspx


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接