3

How can I get the content of an asp:placeholder into a variable that I can apply an xml transform on?

Background

I am trying to customise the layout of a .NET web application. It's an enterprise product that allows me to add/remove blocks of content in ascx files, and change css properties. I don't have access to any CodeBehind files (i.e the .cs source code) but I can possibly write my own .cs's if I know how to add those to the .ascx file. However, the actual content stems from <asp:placeholders> so we build up the page by adding/removing calls to place holders.

The overall aim is to replace the html tables that the place holders generate with e.g. <div> so that the application can be responsive.

Example

An example use of a place holder is

<asp:PlaceHolder ID="TreeHead" runat="server"></asp:PlaceHolder>

which generates the output

<table id="loginBox" style="padding: 2px; margin: 0px;" cellpadding="2">
<tr>
    <td><label for="LM_1">Please enter your username</label></td>
    <td><input name="LM$1$" type="text" id="LM_1" /></td>
</tr>
<tr>
    <td><label for="LM_2">Please enter your password</label></td>
    <td><input name="LM$2$" type="password" id="LM_2"/></td>
</tr>
</table>

I want to convert it to something like this:

<div id="loginBox">
<div class="row">
    <div class="element"><label for="LM_1">Please enter your username</label>  </div>
    <div class="element"><input name="LM$1$" type="text" id="LM_1" />  </div>
</div>
<div class="row">
    <div class="element"> <label for="LM_2">Please enter your password</label>       
</div>
    <div class="element"> <input name="LM$2$" type="password" id="LM_2"/>  </div>
</div>

My idea is

  1. Wrap the <table> in<xml></xml> tags
  2. Transform the table using an xslt
  3. Extract the resulting <div id="loginBox"></div> and output it

I'm thinking that I can achieve this with some inline c# in the .ascx file, like

<% string table = "<xml>" + <asp:PlaceHolder ID="TreeHead" runat="server"></asp:PlaceHolder> + "</xml>"; %>

This fails though as I belive any c# code needs to be in the CodeBehind file so I’m stuck. If I can get the table into a variable, then I can follow this example to apply the transformation. I have found a couple of links (see below) that do something similar but I believe those require access to the Codebehind (i.e. *.cs) files

  1. asp:placeholder contents to string
  2. http://www.tomot.de/en-us/article/3/asp.net/create-a-control-in-the-codebehind-and-retrieve-its-rendered-output

Question

How can I get the content of an asp:placeholder into a variable that I can apply an xml transform on?

Thank you for any help.

Community
  • 1
  • 1
kkuilla
  • 2,226
  • 3
  • 34
  • 37

1 Answers1

3

You are halfway there... you only need to let placeholder renders, then hide the results, transform it, and render your transformation.

place that on page

<asp:PlaceHolder ID="TreeHead" runat="server" /><%= FinalTable %>

and on code behind render and transform your html

using (TextWriter stringWriter = new StringWriter())
{
    using (HtmlTextWriter RenderOnMe = new HtmlTextWriter(stringWriter))
    {
        // render the control
        TreeHead.RenderControl(RenderOnMe);

        // transfor here the stringWriter as you like    

        // now add it to the string
        FinalTable = "<xml>" + stringWriter.ToString() + "</xml>";
    }
}

// hide the control, and only render the FinalTable
TreeHead.Visible = false;

The FinalTable is a page public string

Aristos
  • 66,005
  • 16
  • 114
  • 150
  • Thats for that. Can the code that generate FinalTable be in a different .cs to that of ID="TreeHead" because I don't have access to the source code of "TreeHead"? – kkuilla Jul 04 '13 at 08:35
  • @kkuilla Must be on the page that hold/render that control. However the RenderControl is not always make what you expect especially on complex controls, you need to make a test. – Aristos Jul 04 '13 at 08:39
  • At the top of my .ascx file, it says `<%@ Control Language="C#" AutoEventWireup="True" CodeBehind="IndexMain.ascx.cs"` I don't have access to this file as this is maintained by the software manufacturer. Can I add another CodeBehind and put RenderOnMe there so that the top of the .ascx file looks like `<%@ Control Language="C#" AutoEventWireup="True" CodeBehind="PublicMain.ascx.cs" <%@ Control Language="C#" AutoEventWireup="True" CodeBehind="RenderOnMe.ascx.cs"`? – kkuilla Jul 04 '13 at 08:48
  • @kkuilla This is a different and probably complex question. Make a new question about that. – Aristos Jul 04 '13 at 08:57