Improperly calling EnsureChildControls() will clear your ViewState

I just finished squashing a particularly hard bug to find. I was handing the client a clientID of a server side hidden field control; The client would update that value and, in theory, the value inserted into the hidden field would be available on the server to do whatever I pleased. Well, when I tried to access the field, it was empty. I checked all the usual suspects, but could not find when it was getting cleared.

Weird symptoms

  • initially, I was reusing a hidden field of the base class and it was still coming back blank, even though anywhere the base class was used worked as expected.
  • I could see the value of the hidden field in the Request collection, but it still wouldn’t bind to the object.  Since I was accessing the value when the Request object was out of scope, I couldn’t even scrape the value out of the request object without pushing the Request object all the way up the stack.
  • I was accessing the variable the same way the base class was accessing a similar value.

The Solution

I decided to look up the method that the base class was calling before accessing the hidden value:

EnsureChildControls()

It turns out that this method will recreate the controls. Since it was being called in the base class after ViewState was bound and before I checked the hidden value, the control was recreated and not rebound to ViewState. It was actually being called in a getter of a property, which made it even harder to find the problem.

Since you only need to recreate the child controls once AND they need to be created before the Load event (to allow viewstate to be loaded properly), you can safely call EnsureChildControls() on the Init event of any custom controls. As long as you have created your controls in the .Net CreateChildControls() override.

This entry was posted in Development. Bookmark the permalink.

Leave a Reply

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