ASP.Net Webforms - Dynamic UpdatePanels and UserControls issue
I have come across an interesting issues 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.
Setup
In order to demonstrate, the following path will setup a simple site that has the flaw. The steps work pretty much the same in either .net 3.5 or 4.5, and will show the difference between the versions. In my case I’m using the project templates in VS2013 for this, and I’m using the VB versions.
1: Start a new ASP.Net WebForms project (using the default template)
2: In .Net 3.5 add the following markup:
3: In Default.aspx add the following markup:
4: In Default.aspx.vb add the following code:
Note:
There is a wrapping panel here between the user control and the update panel. This serves to demonstrate what which markup is missing on output.
5: Add a new user control “Control.ascx” into the site root folder and add the following in the markup:
Results
So the portion of markup that we’re insterested is the content of pnlContainer
once we’ve hit btnGo
.
The markup for the two versions is shown below:
3.5
4.5
As you can see, in the 4.5 version, pnlWrapper
is omitted completely - the UpdatePanel update is only returning the content of the user control, not anything else that was added with it.
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)
On investigation the 4.5 behaviour is also there in 4.0 (which isn’t particularly surprising)
Attempting to solve
1: Use LoadControl(type,params) instead of LoadControl(virtualPath).
This method does reproduce the wrapping panel, but none of the content of the user control. See here for a reference to this.
2: Put the update panel in the markup instead of creating dynamically
This works in theory - everything displays, however I’m not going to be able to use this in the project where I have the problem.
Microsoft Connect
I’ve now logged this a Microsoft Connect here If you’re able to reproduce too, then head over there and add a vote to the issue. Hopefully they’ll feedback with something soon.
Workaround
I’ve implemented a workaround which wraps the user control in a server control, and overrides the RenderContent
method on the server control. This allows the user control to be rendered to a separate HtmlTextWriter
and then the content transferred to the main writer instance.
Its a mucky work around, but is working so far in our existing large project (as well as in the above sample).
Here the content of the workaround servercontrol:
UserControlLoader
Usage:
To implement this into the above example the btnGo
event handler becomes: