ASP.Net Webforms – Dynamic UpdatePanels and UserControls issue

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:

<asp:ScriptManager runat="server"></asp:ScriptManager>

2: 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>

3: 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 what which markup is missing on output.

4: Add a new user control “Control.ascx” into the site root folder and add the following in the markup:

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

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

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

4.5

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

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.

Cry for help!

If there is a workaround or fix available for this I’d be most grateful to know of it. If anything to comes to light I’ll update back here.

If you wish to provide a solution, then this question on StackOverflow here. Please post there, and I’ll update this page with any solutions that look reasonable.


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

''' <summary>
''' UserControl Loader - loads a user control
''' Works around a problem with ASP.Net Webforms in 4.0/4.5
''' </summary>
<ToolboxData("<{0}:UserControlLoader runat=server></{0}:UserControlLoader>")> _
Public Class UserControlLoader
    Inherits WebControl

    Public ReadOnly Property Control As Control
        Get
            Return _control
        End Get
    End Property
    Private _control As Control

    Public Sub LoadControl(page As Page, virtualPath As String)
        _control = page.LoadControl(virtualPath)
        Me.Controls.Add(_control)
    End Sub

    Public Overrides Sub RenderBeginTag(writer As HtmlTextWriter)
        'Don't render anything
    End Sub

    Public Overrides Sub RenderEndTag(writer As HtmlTextWriter)
        'Don't render anything
    End Sub

    ''' <summary>
    ''' Overrides RenderContent to write the content to a separate writer,
    ''' then adds the rendered markup into the main HtmlTextWriter instance.
    ''' </summary>
    Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)

        If _control Is Nothing Then Return

        Using sw = New StringWriter()
            Using hw = New HtmlTextWriter(sw)

                MyBase.RenderContents(hw)

                writer.Write(sw.ToString)

            End Using
        End Using

    End Sub

End Class

Usage###:

To implement this into the above example the btnGo event handler becomes:

Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click

    Dim loader = new UserControlLoader()
    loader.LoadControl(Page,"Control.ascx")      

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

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

End Sub

I’m leaving the SO question open for a while to see if a fix comes along instead of this messy work around.

12 thoughts on “ASP.Net Webforms – Dynamic UpdatePanels and UserControls issue”

  1. now a day we all know that almost every people using different type of mobile android and for this popularity there are many people are creating and uploading her app on google play store but i have seen that many app that are not installed more than others, so for this reasons now we are providing a real base android app reviews that will really help you to increase your app install more and more within few days, so visit our site to get more app reviews with best prices

    http://www.buyappreviews247.com/

  2. Thanks for another fantastic article. The place else could anyone get that kind
    of info in such an ideal way of writing? I have a
    presentation subsequent week, and I’m on the look for such info.

  3. Thanks for the marvelous posting! I really enjoyed reading it, you might be a great author.I
    will be sure to bookmark your blog and will come back sometime soon. I want to encourage one to continue your great work, have a
    nice day!

  4. I was very pleased to discover this website. I need to to thank you for ones time due to this wonderful read!!
    I definitely loved every little bit of it and i also have you book-marked to see new stuff in your website.

  5. 歯のホワイトニングでお悩みではないですか?
    人の第一印象は、歯がキレイか汚いかで決まることがあります。
    それほど、歯が白いか黄色いかは大問題なのです。

    欧米では、日本以上に歯のホワイトニングを重要視しています。
    歯のきれいな人はやり手のビジネスマン/ビジネスウーマン。歯の汚い人は冴えないビジネスマン/ビジネスウーマン。
    ハッキリとそう位置付けられてしまうみたいです。

    日本では、そこまでではないけれど、スラっとして美人でいつも憧れの目で見ていた人が、ふとした時に見せた歯が黄色かったらどう思われます?
    一気にそれまでの良い印象が、悪い印象に変わってしまうのでは?

    昔流行った「芸能人は歯が命(いのち)」
    芸能人でなくても、歯は命(いのち)です。
    アナタも歯の美白はじめませんか?

  6. Buy off App Reviews
    Our serve helps app developers become aware of their audience in App Have faith search.
    We have a community of users who by our overhaul to track down unique apps. Our users download and split reviews for apps that we feature and we are known as a service to our talent to push genuine operator feedback, reviews and ratings as far as something developers.

    3x – 10x multiply in organic downloads after working with us.
    Hundreds of app developers attired in b be committed to incorporated us into their marketing plans to widen reviews and ratings in iTunes. We are trusted because our path is effective, promotes inborn growth and is compliant with Apple.

    http://computer-image.ru/bitrix/rk.php?goto=http://6hourapp.com/ – buy mobile app reviews

  7. Предлагаем полностью рабочий софт/We offer a ready solution for FRAUNHOFER EXOCAD 2015 ALL MODULES (CRACK – Dongle emulator/Custom license/Patch). Полная поддержка наших решений. Тестирование перед оплатой/Full support for our solutions. Testing before payment. Контакты/Contacts: nodongle24 /@/ gmail.com (remove spaces and /)

    Guardant Code Time Dongle Emulator, FLEXnet License Manager, ROCKEY 5 Dongle Emulator, Unikey Dongle Emulator, Dinkey 1s Dongle Emulator, Spark Keypro Dongle Emulator, Hasp Hl Dongle Emulator, Guardant Stealth III Dongle Emulator, ROCKEY EPass Dongle Emulator, Katran Dongle Emulator, Keylock 2 Dongle Emulator, Dinkey Dongle Emulator, Proteq C500 Dongle Emulator, Wibu Wibubox Dongle Emulator, Tiny+ Dongle Emulator.

Leave a Reply

Your email address will not be published.

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax