LA.NET [EN]

Nov 16

Today I”ve found another post on the AJAX discussion forums asking info about the “Cannot unregister UpdatePanel with ID XXX since it was not registered with the ScriptManager.This might occur if the UpdatePanel was removed from the control tree and latter added again”.

This happens only in dynamic pages, when you have UpdatePanels added to a certain control and then you move it to another control”s collection after the init event(ie, you remove the control from the 1st control”s collection and add it to the 2nd one). The solution to this is to perform these operations until the end of the PreInit event. If you”re pratical and really don”t care why this happens, then it”s safe to scroll the page or go to the next post (if you”re one of the 3 guys that have subscribed this blog ;),,)

ok, still here? then let”s proceed…to understand why you get that error, you must know the following:

  1. during the Init event, the UpdatePanel control registers itself with the ScriptManager control. You can think of this as putting the UpdatePanel in a list maintained by the ScriptManager control;
  2. during the Unload event, the UpdatePanel unregisters itself with the ScriptManager control. As you”ve already guessed, this means that the UpdatePanel is removed from the internal list mentioned in 1;
  3. you get the previous error when you try to remove an UpdatePanel which is no longer on the internal list maintained by the ScriptManager control

hum, ok…but why am I getting this error? well, what many still don”t know is that when you remove a control from a control”s collection, the unload method of the removed control called. Yes, that”s right! don”t believe me? Ok, use reflector and take a look at the RemoveAt method of the ControlCollection class…so, when you remove the control from a control”s collection and add it to another, that UpdatePanel will be removed from the internal list maintained by the ScriptManager before time. following? let”s enumerate the steps:

  1. during the Init event, the UpdatePanel registers itself with the ScriptManager control;
  2. when it”s removed from a control”s collection, the UpdatePanel unregisters itself with the ScriptManager control;
  3. the UpdatePanel is added again to another control”s collection
  4. during the OnUnload event of the page, the UpdatePanel tries to unregister with ScriptManager
  5. since it”s not in the list, ScriptManager generates an exception

hum…but when I added it to the 2nd control”s collection (as in the previous example), shouldn”t the Init method be called again, resulting in  a new registration? Well, it depends…you see, internally, each control “knows” its current state. So, if you”re removing/adding the UpdatePanel during the Load event, when you add it, you won”t get the Init call because you”re adding the some control and it has already handled the Init event. On the other hand, if you move the UpdatePanel during the PreInit event you won”t get into trouble.

Do keep in mind that this is only valid for removing/adding UpdatePanels maitained in a page. If you”re just creating a new UpdatePanel, then you shouldn”t get this kind of errors.

42 comments so far

  1. Chris
    12:02 am - 11-17-2006

    Thanks for the post. I follow why this is happening, but I added the controls to the page from the control panel in VS 2005. Would you mind posting a possible solution. I do not know how to carry the Init event. I”m fairly new to coding so, please elaborate.

  2. David
    1:11 am - 12-15-2006

    Thanks for the good explanation. Unfortunately, i am droping a user control into a custom Panel control that frames the user control in some common HTML plumbing – a bit like a webpart does for a user control. Anyhow, the user control has an embedded update panel. The custom Panel control overrides the CreateChildControls() method and takes any nested controls (the user control in this instance) and inserts them into the correct HTML container control. This is obviously where the UpdatePanel unregisters itself. How would I force the control tree construction to occur after the PreInit phase? I cant see how i can effect he timing of the control construction.

  3. Rob
    9:13 pm - 12-15-2006

    I”m having the same problem as David.

  4. Rob
    12:06 am - 12-16-2006

    I found a kludge that works for some very specific cases. Here it is:

    I”m no longer inheriting from Panel. I inherit from WebControl.
    I added an ITemplate property to my my Control.
    I created ANOTHER control that implements INamingContainer. Within the constructor of this container I create all my framing controls except for user controls (keep reading). For those, I have private properties for their containers once they”re instantiated.

    My CreateChildControls method instantiates a new sub-container control. Then I call MyTemplate.InstantiateIn(mySubContainer.MyExposedContentContainer) THEN I add this sub-container to this.Controls.

    The problem is that I have to instantiate the user controls in preRender and disable their viewstate otherwise my viewstate gets out of whack. It works for me since those controls are stateless. Is there another way around this? Am I doing something out of order?

    I would like to be able to instantiate those user controls much earlier than prerender, since I know down the line I, or someone else will need to have programmatic access to them.

  5. Morten
    8:02 pm - 3-29-2007

    So basically this means that I can”t add an updatepanel in createchildcontrols, since this occurs after OnInit? Hmm…

  6. cmwalolo
    10:41 am - 5-4-2007

    http://dev.cmwa.eu/Products/ASPNet/AJAXStuff/tabid/68/Default.aspx

    Here some sample that can make it … The idea is to load your customcontrols only on the prerender.

    I made some test pages with some PanelManagement class. That can handle this easily.

  7. Loco
    6:57 am - 5-8-2007

    cmwalolo…. can”t seem to find the link to download your sample. I”m getting the dreaded “Cannot unregister UpdatePanel ” error too. Help a brother out.

  8. Luis Abreu
    8:34 am - 5-8-2007

    Hello.

    I believe that doing that might work since you”re loading your control. It wont work, however, if you load you control (that has your panel) and then remove it from the current hierarchy and add it as a child control of another control.

  9. Constantine
    2:21 pm - 5-23-2007

    Interesting…

  10. Bassam
    3:03 pm - 6-8-2007

    Hi there

    well i am getting the same error which you have discussed about, and i am not able to understand what / how to get a fix round of it.

    my scenario is that i have a user control, UC1. i will drop it in an UpdatePanel UP1 on a wizard control WC1 step page, on the Main .aspx page. like

    WC1 contains UP1; UP1 contains UC1

    i have the script manager declared rite under the form tag on the master page, and all seems good / smooth to me, but still I WILL GET THIS ERROR :(.

    please help me over this error. Waiting for your reply.

    – Bassam

  11. Yannas
    12:47 pm - 6-10-2007

    Interesting…

  12. Alexios
    10:28 am - 6-14-2007

    interesting

  13. Evripides
    12:01 am - 6-16-2007

    interesting

  14. Halu
    12:24 am - 6-18-2007

    interesting

  15. Kymon
    11:23 am - 6-19-2007

    Interesting…

  16. Odysseas
    6:50 am - 6-20-2007

    interesting

  17. Kymon
    6:58 pm - 7-17-2007

    Interesting…

  18. Gerasimos
    4:23 am - 7-18-2007

    Interesting…

  19. Mamadshah
    11:05 am - 7-28-2007

    interesting

  20. Iannis
    5:31 am - 7-29-2007

    Interesting…

  21. Interesting
    12:01 pm - 9-13-2007

    If you mo-fo”s don”t know the answer, just say so..!
    Some of us would actually appreciate the help.

  22. bakuuu
    12:20 pm - 9-24-2007

    Great, but I have an another problem.
    I have been trying to set programatically visible and unvisible of some Controls in my WebPage. On this Controls there are UpdatePanels.
    On each control – one UpdatePanel.
    I have to set visible = true/false in “Page_PreInit” method, it works on single test site, but…

    In my project I have a MasterPage, and in method Page_PreInit a reference to my control is null, so I can”t change visible, and masterpage has no PreInit method.
    How to solve it ? Maybe you know some other solution to dynamic hide controls with updatePanel in it.

  23. Goldfinger
    8:32 pm - 3-27-2008

    FOR GOD…. WRITE THE DAMN SOLUTION

  24. Serializer
    11:49 pm - 4-6-2008

    Yet another example of how broken ASP.NET is.

    Why design this great component model, yet not actually build in the flexibility to use it properly?

    It makes building web applications ultimately take about 100x as long, rather than saving time as it”s supposed to – since I seem to spend all my time figuring out how to work around ridiculous inflexibilities like this.

    I can”t use the Page_PreInit event to insert my user control containing the update panel – because Page_PreInit has fired *way* before my other nested controls are ready to set themselves up.

    Microsoft recommend that dynamically-added controls should be added in the Load method. This dynamically added control contains a templated control, which in turn instances a further user control within itself – sometimes this control will also contain an UpdatePanel. I simply can”t do this at PreInit – the other page controls that I need to insert into aren”t available at this time.

    Don”t know what to do but somehow I will kludge this mess, then wait for MVC toolkit to drop so I can start building things *properly*.

  25. Luis Abreu
    8:19 am - 4-7-2008

    Hello.
    yeah, the web forms model has some gotchas….

    but do notice that you can still add the UpdatePanel during the load event. what you cannot do is add/remove/add again after the event i”ve mentioned…the problem I”m describing happens because there are some cases where a control (which internally contains an UpdatePanel) is initially added to an existing control, then removed and then added again to another controls”s collection. if you do this, then be sure to do it until the preinit event.

    If you”re just adding a control to the page (and you”re nov removing it/adding it to another place later) you should be able to do it until the end of the load event…

  26. Kominsky
    6:13 pm - 4-16-2008

    Well, as som have said, there”s a lot of complaining about this issue, but I can”t see solutions, plx! if someone has a solution, post it here, I really need it, and well, I”m still lookin” for it, so if I get it, I”ll post it here for sure.

    My problem is:
    aspx-contains the follow:

    scriptManager1
    updatePanel1
    ascx1{updatePanel2[ascx2]}

    when I try to update updatePanel2, I got that error…
    By the way, my ascx 1 and ascx2 are loaded in the Page_Load cuz they are dynamic too…

    PLX! HELP!

  27. Kalam
    6:02 pm - 5-3-2008

    I have migrated to .Net 2.0. There are some custom controls on the page including form and panel. This controls are mandatory for the page and form. Now while I want to implement ad ajax withih the page I get this error. How to deal with ajax and custom control in VS 2005. Any suggestion will be appriciated.
    Please help
    Thanks

  28. Tommy
    6:16 pm - 8-28-2008

    Well, I”ll go ahead and add this. The problem is removing the Update Panel and then adding it back again. The solution is to not have the Update panel there in the first place, just load it dynamically. Here”s how I got the error, and then what I did to fix it.
    –I have a Panel with an Update Panel inside of it on my page.
    –I wrote a User Control to extend this panel with some extra functionality.
    –The user control basically wraps the panel , so I have :

    –I wrote the Panel up in Visual Studio on the page, and set that Panel to be the Target of my Extender user control, which placed it in the PlaceHolder.

    So here”s what happens: Page_PreInit runs, puts the Panel with the UpdatePanel on the main page.
    Page_Load runs, Removing the Panel from the Page Hierarchy, and then placing it in the UserControl hierarchy (this is where it breaks)…

    So here”s what I did. Instead of designing the Panel on the Page, I create a second user control with the same markup as the Panel. Then, instead of PlaceHolder.Controls.Add(Panel), I do PlaceHolder.Controls.Add(LoadControl(“myControl.ascx”))

    As for code behind on the was-panel-now-userControl, you can either put it in the UserControl, or you can simply pass through the relevant events to the page by registering your own events for the new UserControl.

    No, it”s not the simplest solution, but it”ll work.

  29. Philippe
    9:13 pm - 9-4-2008

    Thought I”d share this solution with you…

    The problem is that when the UpdatePanel unloads, it is also unregisters itselfs. That being a fact, the solution is to register it again.

    Unfortunately, the method to register an UpdatePanel is private so reflection is the key to invoke said method.

    public void RegisterUpdatePanel(
    UpdatePanel panel)
    {
    MethodInfo m =
    (from methods in typeof(ScriptManager).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
    where methods.Name.Equals(“System.Web.UI.IScriptManagerInternal.RegisterUpdatePanel”)
    select methods).First();

    m.Invoke(ScriptManager.GetCurrent(Page), new object[] { panel });
    }

    When the UpdatePanel is created, simply hook an handler on it”s Unload event and call the RegisterUpdatePanel method.

    Unfortunately, I cannot guarantee this will work in future Framework build but at the same time, they might just have fixed the issue.

    Hope this helps…

  30. rüya tabiri
    4:48 am - 9-6-2008

    Thanks very much !!

  31. Paul
    12:23 pm - 9-23-2008

    Philippe – that”s a real nasty hack!! But it works and I love it – thanks!

  32. Vlady
    9:51 pm - 11-13-2008

    Please write the code in visual Basic a with real case

  33. Gary
    10:34 pm - 12-10-2008

    Thanks Philippe for the solution.

    I had struggled with the same problem. I was able to convert your solution to VB and I have provided it below for anyone who is also struggling with this.

    Public Sub RegisterUpdatePanel(ByVal sender As System.Object, ByVal e As System.EventArgs)

    Dim panel As UpdatePanel = Me.UpdatePanel1
    ”Dim aMethodInfo As System.Reflection.MethodInfo
    For Each aMethodInfo As System.Reflection.MethodInfo In GetType(ScriptManager).GetMethods(System.Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
    If aMethodInfo.Name.Equals(“System.Web.UI.IScriptManagerInternal.RegisterUpdatePanel”) Then
    aMethodInfo.Invoke(ScriptManager.GetCurrent(Page), New Object() {panel})
    End If
    Next

    End Sub

    ‘ You can then call this method with something like this from the Page_Int.
    AddHandler Me.UpdatePanel1.Unload, AddressOf RegisterUpdatePanel

    I hope this helps.

  34. marcel
    12:03 pm - 3-12-2009

    Phillipe, i am getting errors: can”t find methodinfo and BindingFlags
    does it need a using directive or something?

  35. Thanks!
    5:58 pm - 4-23-2009

    Thank Phillipe, it works like magic

    And thanks Gary for the VB transalation.

  36. Noel
    2:09 am - 12-10-2009

    Thanks Phillipe that solution was exactly what i needed! You saved me some headaches.

  37. Henrik
    10:20 am - 1-5-2010

    I have a sample project for this problem.
    It” shows tabcontainer and updatepanel problem.
    Read about it here.

    http://blogg.pixcode.se/post/Working-with-ajax-tabContainer-and-ajax-updatepanel.aspx

  38. scott
    4:24 am - 3-23-2010

    Marcel, you neeed

    using System.Reflection;

    C# coders: here”s another synopsis

    using System.Reflection;

    protected override OnInit(EventArgs e)
    {
    someUpdatePanel.Unload += new EventHandler(UpdatePanel_Unload);

    // this used to cause the error… but now it doesn”t
    SomeMethodThatManipulatesTheDom();
    }

    void UpdatePanel_Unload(object sender, EventArgs e)
    {
    RegisterUpdatePanel(sender as UpdatePanel);
    }

    public void RegisterUpdatePanel(UpdatePanel panel)
    {
    MethodInfo m = (from methods in typeof(ScriptManager).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
    where methods.Name.Equals(“System.Web.UI.IScriptManagerInternal.RegisterUpdatePanel”)
    select methods).First();

    m.Invoke(ScriptManager.GetCurrent(Page), new object[] { panel });
    }

  39. Norman
    12:26 pm - 3-25-2010

    using System.Reflection

  40. Smith
    11:48 pm - 4-22-2010

    Doesn”t throw the error but at the same time causes full pagepostback…Any ideas?

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>