If I create a UserControl and add some objects to it, how can I grab the HTML it would render?
ex.
UserControl myControl = new UserControl();
myContr
You could utilize the HttpServerUtility.Execute
Method, available through 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);
The benefit would be that you also trigger the Page_Load event of your user control.
MSDN documentation can be found here: https://msdn.microsoft.com/en-us/library/fb04e8f7(v=vs.110).aspx.
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();
Call its .RenderControl()
method.
You can render the control using Control.RenderControl(HtmlTextWriter)
.
Feed StringWriter
to the HtmlTextWriter
.
Feed StringBuilder
to the StringWriter
.
Your generated string will be inside the StringBuilder
object.
Here's a code example for this solution:
string html = String.Empty;
using (TextWriter myTextWriter = new StringWriter(new StringBuilder()))
{
using (HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter))
{
myControl.RenderControl(myWriter);
html = myTextWriter.ToString();
}
}
Seven years late, but this deserves to be shared.
The generally accepted solution - StringBuilder
into StringWriter
into HtmlWriter
into RenderControl
- is good. But there are some gotchas, which I unfortunately ran across while trying to do the same thing. Some controls will throw errors if they're not inside of a Page
, and some will throw errors if they're not inside of a <form>
with runat="server"
. The ScriptManager control exhibits both of these behaviours.
I eventually found a workaround here. The gist of it is basically just instantiating a new Page and Form before doing the writer work:
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();
Unfortunately, this gives you more markup than you actually need (since it includes the dummy form). And the ScriptManager will still fail for some arcane reason I haven't puzzled out yet. Honestly, it's a whole lot of trouble and not worth doing; the whole point of generating controls in the code-behind is so that you don't have to fiddle around with the markup, after all.
//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();