32

I have any ASP.NET control. I want the HTML string how to do I get the HTML string of the control?

David Basarab
  • 72,212
  • 42
  • 129
  • 156

3 Answers3

45

This appears to work.

public string RenderControlToHtml(Control ControlToRender)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    System.IO.StringWriter stWriter = new System.IO.StringWriter(sb);
    System.Web.UI.HtmlTextWriter htmlWriter = new System.Web.UI.HtmlTextWriter(stWriter);
    ControlToRender.RenderControl(htmlWriter);
    return sb.ToString();
}
David Basarab
  • 72,212
  • 42
  • 129
  • 156
  • 7
    The StringWriter and HtmlTextWriter both implement IDisposable, so you might want to wrap them in a using() {} block. Also, it might be useful to make this an extension method of 'Control', so you can call it from an instance member. – Joe Blazek Nov 09 '12 at 15:44
  • 1
    @David, how did you end up with render an ascx file to html? I tried above method, but always get "Object reference not set to an instance of an object.", saying the user control I am referencing is not an instance. How should we use it in windows form or console application? – Princa Apr 30 '13 at 19:28
  • 1
    The default StringWriter() constructor creates a new string builder, so the first two lines can be replaced with just System.IO.StringWriter stWriter = new System.IO.StringWriter(); – Spongeboy Apr 09 '14 at 00:53
  • This always gave me an empty string. However, a7drew's solution worked like charme. – Tillito Mar 13 '15 at 19:58
  • I pass new Controls.sidebar() to the function, but I get empty string, although the control renders html when run inline. – Liron Harel Jul 07 '15 at 11:02
  • this will not work unless control is part of the page. – avs099 Sep 24 '15 at 15:53
16

Accepted answer by David Basarab will not work if control is not part of the page. a7drew's answer seems unnecessary complex - no need in Context or Server.Execute.

private string RenderControl()
{
    var sb = new System.Text.StringBuilder();
    using (var stWriter = new System.IO.StringWriter(sb))
    using (var htmlWriter = new HtmlTextWriter(stWriter))
    {
        var p = new Page();
        var ctrl = (YourControl)p.LoadControl("~/controls/building blocks/YourControl.ascx");
        ctrl.Visible = true;

        // do your own init logic if needed

        p.Controls.Add(ctrl);
        ctrl.RenderControl(htmlWriter);
        return sb.ToString();
    }
}
avs099
  • 10,937
  • 6
  • 60
  • 110
  • Thank you, this works! By the way, in my testing, the `ctrl.Visible = true;` line seems not to be needed. – Otto G Apr 12 '16 at 10:34
  • Thank you! I had a method that worked but for a service but not when called from an API. This works! – Adam Mendoza Sep 10 '19 at 03:11
  • I see that `ctrl.Visible = true;` as an ensurance / failsafe. In my case, the control had @Visible="false"@ in markup, determining it to be rendered as an empty string. – liviriniu Jan 12 '23 at 01:16
6

If your control is a web user control, this is how you can get to the HTML it emits from another page or handler:

public void GetHtmlFromMySweetControl(HttpContext context)
{
    HttpRequest httpRequest = context.Request;
    HttpResponse httpResponse = context.Response;

    string foo = httpRequest["foo"];

    Page pageHolder = new Page();
    string path = "~/usercontrols/MySweetControl.ascx";
    MySweetControl ctrl = (MySweetControl)pageHolder.LoadControl(path);
    ctrl.BindProducts(foo);
    pageHolder.Controls.Add(ctrl);

    StringWriter sw = new StringWriter();
    context.Server.Execute(pageHolder, sw, false);
    httpResponse.Write(sw.ToString());
}
a7drew
  • 7,801
  • 6
  • 38
  • 39
  • When I try this, the HTML rendered out is different than what would normally appear on the page. For instance, an asp:Panel with an GroupingText attribute. The value of the GroupingText attribute is rendered now as a fieldset and legend. This is not desirable... its like the UserControl is being rendered under some different kind of mode.... completely different HTML... :( – Jason Parker Nov 26 '12 at 17:45
  • Nice! I did not even know this was possible! This allows very efficient ways of caching content! Thanks a lot! – Tillito Mar 13 '15 at 19:59