views:

42

answers:

3

I am dynamically generating controls, and sometimes I want to create a control and have it ignore the viewstate. For example, sometimes the user has clicked a button indicating they want a different form loaded, so the control tree I generate on postback is different from the original control tree. This is fine, except when I call Controls.Add then it tries to load the viewstate form the old controls into the new controls if the control tree structure is similar, and I want them to instead ignore that viewstate(and also ignore the postback values for input controls as well).

Can I do something like set the IDs of the controls or something that would allow me to conditionally prevent them from getting the viewstate/postback data of the previous request?

Edit: If I let the user of the control load the form on demand in postback handler, the postback data is not applied when I call Controls.Add(this really seems like a flaw in ASP.NET, because I would think if you're going to apply viewstate data "after the fact" through Controls.Add, it'd seem you would then apply the postback data automatically as well after the viewstate data is loaded). The real problem I run up against is my control is very dynamic, but the user of my control can't really tell it what to do until their postback handler fires, because one of the things a user can do is select different forms to be loaded via some link buttons. So it's not until the postback handler runs that they know what the uesr requested, and thus can ask my control to load a certain form. So I have to ask them to do convaluted things like saved the formID that identifies the last form to a session variable, and in OnInit they tell my form what the old formID was via a property. My control then loads the form in OnLoad so that it can consume the viewstate and postback data, and later in the programmer's postback handler, they can choose to clear the form and load a different one if they want.

Edit2: FYI Generating IDs for each control unique to the form works great, so I thought I could eliminate the pointless loading of the old form until the programmer requests a form be loaded in his postback handler. But as I mentioned above, what I found was that loading the form after postback data handling has occurred means that data is lost. Whereas viewstate gets loaded via Contorls.Add, playing catch up in the page lifecycle, it seems postback data does not! So it seems I am defeated at every turn.

+1  A: 

Giving the controls different ID's would certainly prevent ViewState from being loaded, that would be one way.

You may also be able to manipulate the ViewStateMode property of your controls by setting it to "Disabled". I'm not sure if this prevents it from loading (it definitely prevents them from saving viewstate), but you could try it.

womp
+1 Everyone, but I am marking this as the answer because it directly addressed the question asked about ignoring viewstate. Also, setting the IDs will remain part of my solution even though I couldn't really eliminate the loading of the old form, it will be important whenever I can't load the old form because it is no longer valid so that I can ignore the viewstate(long story I won't get into). Suffice to say thanks.
AaronLS
+1  A: 

Have you tried just calling controls.clear prior to adding in the new ones?

UPDATE

I'm starting to believe that you are generating the controls at the wrong point in the page lifecycle. What is your flow?

Chris Lively
I did try that, and what I had to do as a workaround was during postback, generate the previous form dynamically so that they can consume the viewstate/postback, and then call Clear, and then create the new form. If I didn't generate the old form before calling clear, the controls didn't exist in the form yet, and so the viewstate would still be waiting and get applied to the new form, which often resulted in an exception when control types were different.
AaronLS
I have tried various combinations of onload, oninit, and also on demand by a function call from the user of my control(who calls from a postback handler like a button click), but regardless when you call Controls.Add then asp.net runs your controls through all the events that have occurred already, so viewstate gets loaded regardless. So in my testing it doesn't seem to make a difference either way.
AaronLS
Actually I lie because postback data is lost if I add the controls too late in the lifecycle. See edit.
AaronLS
+3  A: 

You're going to avoid problems if you play along with the control lifetime. Basically, whenever you have a control that renders, it's best to ensure that control is recreated on the next postback, even if you aren't going to need it anymore. The first goal of a postback should be to restore the previous state -- only THEN do you make changes to it.

I described it best in this answer:

http://stackoverflow.com/questions/2214023/wrong-state-in-server-controls-with-same-ids-when-dynamically-adding-usercontrol/2261965#2261965

InfinitiesLoop
+1 this is a good answer to the problem
Chris Lively
Ugghhh I think you are right, there is going to be no way around it.
AaronLS