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.