Dynamic UpdatePanels and UserControls issue

Viewed 600

Have come across an interesting issue in ASP.Net WebForms when migrating a project from 3.5 up to 4.5.

The site in question is extremely dynamic - the page is built up based on configuration in a CMS fashion.

However in 4.5 we have a problem – when more content is added into the page via a button click, not all the markup for the content appears. (On testing the problem is reproduced in .net 4.0 as well).

To demonstrate here is a much stripped out example that just uses the default WebForms project template (in VB in this case).

In Default.aspx add the following markup:

<asp:UpdatePanel ID="udpTrigger" runat="server" UpdateMode="Always">
    <ContentTemplate>
        <asp:button id="btnGo" runat="server" Text ="Go" />
    </ContentTemplate>
</asp:UpdatePanel>
<asp:Panel ID="pnlContainer" runat="server">
</asp:Panel>

In Default.aspx.vb add the following code:

Dim _udp As UpdatePanel

Private Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init    
    _udp = New UpdatePanel()
    _udp.ID = "udpTarget"
    _udp.UpdateMode = UpdatePanelUpdateMode.Conditional

    pnlContainer.Controls.Add(_udp)        
End Sub

Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click    
    Dim ctrl = LoadControl("Control.ascx")        

    Dim pnlWrapper = New Panel With {.ID = "pnlWrapper"}
    pnlWrapper.Controls.Add(ctrl)

    _udp.ContentTemplateContainer.Controls.Add(pnlWrapper)        
    _udp.Update()            
End Sub

Note: There is a wrapping panel here between the user control and the update panel. This serves to demonstrate which markup is missing on output.

Create a Control.ascx and add the following:

<asp:Panel ID="pnlControl" runat="server"></asp:Panel>

Once we click the btnGo control, the wrapper panel and control.ascx should be added to the page.

In .Net 3.5 that is exactly what happens:

<div id="pnlContainer">                    
    <div id="udpTarget">
        <div id="pnlWrapper">
            <div id="ctl05_pnlControl">
            </div>
        </div>
    </div>
</div>

In .Net 4.5, the wrapping panel doesn't appear - just the user control:

<div id="MainContent_pnlContainer">          
    <div id="MainContent_udpTarget">
       <div id="MainContent_ctl02_pnlControl">
       </div>
    </div>
</div>

The problem doesn't occur if the update panel is in the markup of the webpage, however that's not possible in this case.

Switching which LoadControl overload is used (to LoadControl(type,params) produces the wrapper panel, but no markup - there appears to be a separate issue with this).

Checking the response body in fiddler2 shows that the wrapper panel is omitted at server side (ie we're not losing it in the client side ajax processing)

So is there any workaround, or even some sort of fix patch for this behaviour - it does seem to be a breakage in .Net 4 given that it was fine in 3.5.

Have also now posted this on my blog here to collect any attempts I make to get a fix or workaround.

Update

Following a pointer from @jadarnel27 that the below steps did not reproduce the problem on VS2010, I've tried the steps on a couple of machines away from work.

  • First off another VS2013 machine: Did recreate the issue.
  • Next, my old dev machine, running VS2012 Express For Web: Did not reproduce the problem

So it looks at this stage like the problem is restricted to VS2013. Next to try a few different settings in VS2013.

Have now posted this to Microsoft Connect here.

2 Answers
Related