5

Simple question but I can't find anything on it, is it possible to get the contents of an asp:placeholder to a string? This would be great to do server side if it is possible.

Luke

Luke Wilkinson
  • 439
  • 8
  • 17
  • 1
    What means _"contents of an asp:placeholder to a string"_? Do you want the genrated html or do you want the textual content of a placeholder on serverside? – Tim Schmelter Jan 14 '13 at 16:02

2 Answers2

10

If you just want the textual content of a placeholder:

string textualContent = ((LiteralControl) PlaceHolder1.Controls[0]).Text;

Returns "Hello World" for:

<asp:PlaceHolder ID="PlaceHolder1" runat="server">Hello World</asp:PlaceHolder>

If you also want to get the html of the rendered control (and all of it's child-controls):

System.IO.TextWriter tw = new System.IO.StringWriter();
HtmlTextWriter h = new HtmlTextWriter(tw);
PlaceHolder1.RenderControl(h);
string html = tw.ToString();

For this aspx (the GridView is databound with some sameple data):

<asp:PlaceHolder ID="PlaceHolder1" runat="server">
    <asp:Label ID="LblTest" runat="server">Test-Label</asp:Label>
    <asp:TextBox ID="TxtTest" runat="server" Text="Foo"></asp:TextBox>
    <asp:GridView runat="server" ID="GridView1"></asp:GridView>
    <textarea name="TextArea1" rows="2" cols="1">
    First line
    Second line
    </textarea>
</asp:PlaceHolder>

this html will be generated (depends on the browser):

<span id="MainContent_LblTest">Test-Label</span><input name="ctl00$MainContent$TxtTest" type="text" value="Foo" id="MainContent_TxtTest" /><div>
    <table cellspacing="0" rules="all" border="1" id="MainContent_GridView1" style="border-collapse:collapse;">
        <tr>
            <th scope="col">ID</th><th scope="col">Text</th>
        </tr><tr>
            <td>1</td><td>Row #1</td>
        </tr><tr>
            <td>2</td><td>Row #2</td>
        </tr><tr>
            <td>3</td><td>Row #3</td>
        </tr><tr>
            <td>4</td><td>Row #4</td>
        </tr><tr>
            <td>5</td><td>Row #5</td>
        </tr>
    </table>
</div>
    <textarea name="TextArea1" rows="2" cols="1">
    First line
    Second line
    </textarea>

Note that you need to change your page directive to

EnableEventValidation="false"

and to override VerifyRenderingInServerForm in the Page

public override void VerifyRenderingInServerForm(Control control)
{
    /* Confirms that an HtmlForm control is rendered for the specified ASP.NET
       server control at run time. */
}

when calling RenderControl manually.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Do I need to add anything to the override of VerifyRenderingInServerForm for it to work? Currently my repeater control is not working? – Luke Wilkinson Jan 15 '13 at 13:32
  • Sorry that wasn't a very helpful description. Nothing gets rendered in the repeater, I have put a breakpoint in the page load of the usercontrol that is called and it does not get hit. Is there a setting in the web.config that is global for EnableEventValidation="false"? All the code in the ascx works and is displayed but the c# codebehind does not get called? – Luke Wilkinson Jan 15 '13 at 13:46
1

Try the RenderControl method of the Placeholder.

I did something like this for a HyperLink, but as a Placeholder inherits from System.Web.UI.Control, that should work exactly the same. Something like this:

StringBuilder sb = new System.Text.StringBuilder();
using (var stringWriter = new System.IO.StringWriter(sb))
{
    using (var htmlTextWriter = new System.Web.UI.HtmlTextWriter(stringWriter))
    {
        YourPlaceHolder.RenderControl(htmlTextWriter);
    }
}
return sb.ToString();

I've written a short article about this topic: http://www.tomot.de/en-us/article/3/asp.net/create-a-control-in-the-codebehind-and-retrieve-its-rendered-output

citronas
  • 19,035
  • 27
  • 96
  • 164