When you create an ASP.NET page with no controls and runs it, a view state hidden field is added.
Looking at what's in it (with ViewStateDecorder) reveals that there's a single value there that contains a number.
My question is - what is this number?
P.S. I guess this value appears on every page, with or without controls.
The ASP.NET page stores a hash code in the "__VIEWSTATE" hidden field that is used to ensure that the view state hasn't been tampered with between postbacks.
Related
I'm trying to create multiple controls by using retrieved data from query, but preventing them from dissapearing on postback, allowing me to get and mantain their values, the problem I have is that I cannot create them on Init because the number of controls, their IDs, and other properties are only known after user selects an item on menu.
Page loads a Menu with all its items and values (Data dependent), plus, a button is loaded too
User clicks a item on menu.
Selected value is used to perform a query by using a Dataset (This happens inside a function which is called from Menu_ItemClick event).
Retrieved data from query is used to determine how many controls must be created (2, 4, 6, etc.). Each control has its unique ID, which is given according to data.
Controls are created and placed into a Panel (named p).
Now controls are visible and available for editing (RadioButtons, TextAreas)
User clicks on button to save information from dynamic controls into a Database
Problems I'm facing
Controls dissapear on postback when clicking button, because they weren't created on Init.
Placing button on UpdatePanel to prevent whole page postback, makes dynamic controls not accesible when trying this:
For Each c In p.Controls
...
Next
The only control it gets is a single Literal control (Controls count is 1), as if other controls didn't exist.
Thank you in advance.
When you wrote "Controls dissapear on postback when clicking button, because they weren't created on Init", did you mean to say that "Controls dissapear on postback when clicking button, because they weren't re-created on Init"? If not, then that is likely a root cause of your problem - dynamically-created controls must always be recreated in response to a PostBack (cf. ASP.NET dynamically created controls and Postback). There may be other issues as well, as dynamic controls in Web Forms can provide a lot of challenges as your scenario gets more involved - here's one article that lays out many of them under various scenarios http://www.singingeels.com/Articles/Dynamically_Created_Controls_in_ASPNET.aspx (e.g., if the user can re-select from the DropDownList to generate a different set of dynamic controls). The canonical reference on all of this is http://msdn.microsoft.com/en-us/library/ms178472.aspx.
Now, on PostBack you'll need some way to ascertain which controls were dynamically created so they can be dynamically re-created. As such, you'll need to store somewhere whatever information allowed you to dynamically create the controls. Since ViewState isn't available in Page_Init and there can be other issues introduced when using sessions, my suggestion is to simply declare a HiddenField that contains that state information. In Page_Init, you'll then need to get the HiddenField's value from Request.Form (since the value of your HiddenField won't be loaded until after Page_Init from ViewState) and go from there to re-create your controls.
My final suggestion: try getting everything working with a regular Panel first and then try and introduce the UpdatePanel - no need to over-complicate the problem at first.
I have a Panel. Now in that panel, i'm adding controls. It is getting added and displayed.The problem is when the page is posted back.I know the controls have to be binded again in the panel. But lets say if the user has entered some value in the dynamic created text box. Its is getting lost..
I have done this before by storing the data from the controls in session.
Every time you dynamically add a control, store the current data entered into the controls in session or viewstate for example, and then rebind on postback. Not the most elegant solution but it worked. I take it this is a webforms question?
Add dynamic control click
Save current form data
On page_load load the data from viewstate into the controls
Make sure that the controls get the same ID each time (for ex. by specifying an ID explicitly)
and you should add the dynamic controls on Page.Init so they can participate in the page's life-cycle.
There's an article on 4guysfromrolla.com, Dynamic Web Controls, Postbacks, and View State
I have two Repeater controls, each hosted in a user control. Both user controls are contained in the same aspx page. Only one User Control is visible at any one time. The repeaters are comprised of checkboxes, and text boxes for user input.
The aspx page is configured with an Ajax ScriptManager; and contains several Ajax UpdatePanels. These UpdatePanels result in partial page post backs when text is changed in a textbox control in controls on the aspx page (this is not the behaviour for the Repeaters in the User Controls). Through use of several AsyncPostBackTriggers, various controls contained in the other UpdatePanels on the page have their content refreshed in response to the partial page post backs they are configured be notified about.
Depending on a radio button group selection, I set the visible property to true or false – as appropriate for the User control containing a repeater control. The Repeater control is then populated with data using databinding. All of this works.
However, when the Submit button is clicked, the Repeater control contains no data.
Given that I am not dynamically adding the Controls containing the Repeater controls (but using Visible true / false). I would have thought that the State of the fields and the data in the visible control would be preserved during the post back.
The User Controls are contained within the UpdatePanel that contains the Submit Button.
I have explicitly Enabled View state without any effect.
Am I correct in assuming that I should not have to do any explicit handling of data changes the user makes (via client side script and manipulation of an Data Structure Representing the Repeater Data); and the View State should maintain the data I need to access on the server when submitted?
I do not believe that it is the User Control visible state changes that are causing the issue because when the page is initially loaded on of the User controls is populated with dummy rows (so it displays).
I am suspicious that because the visible state of the controls is changed during partial page post back, that the Page View State ends up with no knowledge of the User Control and therefore cannot track its data (or changes).
I have investigated a lot of similar sounding posts but so far do not feel that I have come across a solid explanation that can help me understand and fix the issue.
Hopefully someone can help.
I must be the only person who was unaware of the finer points of DataBind() method; be it called on a specific control being bound to data; or on the page itself. I hope the below helps others who find themselves in a position where data binding appears to be inexplicably lost'.
My problem was that my page was pretty complex. It has several User Controls on it. The problem was that in these User Controls, I was calling Page.DataBind() in the Page_Load event handler to 're-bind' the page data on PostBacks. This resulted in the Repeater control located on another User Control, to lose its data binding.
Removing the Page.DataBind method call from each of the User Controls on the Page_Load event handler method resolved the problem. It had nothing to do with Update panels / refreshes etc.
I sort of answered my own question I think but I want to make sure I am understanding correctly. I initially thought that when a user provided values in a form, that on postback the values were submitted as part of the Viewstate, because TextBox.Text is part of the viewstate. Now I have found that user supplied values actually aren't applied to the controls until after the OnLoad event. This confused me because I thought that viewstate was loaded into the controls before OnLoad(or when calling Controls.Add()). I have gone over the documentation on page and control lifecycles a few times and I am just now realizing that there was a different step for handling postback data(this step didn't appear in a lot of documentation :(
1) So postback data, the values user's type into the fields, is applied after the OnLoad event, and Viewstate data is applied just before the OnLoad event?
2) So essentially all this means is that on postback the server gets two values for a TextBox.Text property, the one in Viewstate, which is like the "old" value from the previous request, and the new value supplied by the user in the form?
3) Does the .net framework apply postback data the same was as Viewstate, in that it finds the appropriate control via it's ID property? This is important because I am creating controls dynamically and I may even have forms that change structure overtime and need to think about how I handle ID's. So far I haven't been setting the ID property and everything works fine but things may be more complicated later on.
4) Does viewstate data ever get modified at all on client side? Or is the viewstate identical to what was sent by the server in the previous request(assuming no tampering)? My impression used to be that the server encoded all the control properties into the viewstate, and on the client side when the user submitted the form, the viewstate field was decoded, modified, encoded, and submitted to the server with modifications. I assumed there was a bunch of javascript doing all this for me. Now I think I had it all wrong. Instead it seems that the Viewstate never changes on client side, and all the client changes are in the postback data such that the next request the server loads viewstate, loads postback, and provides a new updated viewstate in the next response?
1) Both are loaded before Load
2) Basically, yes
3) ViewState is applied first, then Post Data
To quote Scott Mitchell(see below)
dynamically added controls must be
programmatically added to the Web page
on each and every page visit. The best
time to add these controls is during
the initialization stage of the page
life cycle, which occurs before the
load view state stage. That is, we
want to have the control hierarchy
complete before the load view state
stage arrives. For this reason, it is
best to create an event handler for
the Page class's Init event in your
code-behind class, and add your
dynamic controls there.
4) Unless you're doing something way outside of the box, ViewState is never modified client-side. "ViewState" is an HTML form field and is processed on the server side.
Here's a few images from Understanding ASP.NET View State by Scott Mitchell that may help you.
(source: microsoft.com)
(source: microsoft.com)
Bonus Reading Material: http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx
My impression used to be that the server encoded all the control
properties into the viewstate, and on the client side when the user
submitted the form, the viewstate field was decoded, modified,
encoded, and submitted to the server with modifications.
No, the point of the ViewState is simply to preserve the state of the page since the last "Save View State" page event, i.e. that event occurs shortly before the page is rendered to the client.
When the client makes selections to a dropdown box or changes text in a textbox the hidden ViewState property, which exists on the client page as a static HTML tag, is not dynamically changing / encoding those values, it remains the same as when the page was originally rendered.
So how is the new state of the page being preserved, i.e. how are user dropdown selections and text box values retained in ASP controls? Those dropdown selections and text box values are captured in Post Back data.
A server control can indicate that it is interested in examining the posted back data by implementing the IPostBackDataHandler interface. In this stage in the page life cycle, the Page class enumerates the posted back form fields, and searches for the corresponding server control. If it finds the control, it checks to see if the control implements the IPostBackDataHandler interface. If it does, it hands off the appropriate postback data to the server control by calling the control's LoadPostData() method. The server control would then update its state based on this postback data.
- Scott Mitchell
I'm looking for an easy way to explain this to someone. Apologies if it has been asked before.
It is a way to persist the page state between postbacks on the client. It represents a serialized string of the state of a page stored inside a hidden field and posted to the server at each request/postback (ASP.NET uses a single form and every time the user performs an action like clicking on the button this form is submitted to the server). Once the serialized state is submitted to the server it is capable of retrieving values that have been stored inside the view state.
Further reading: Understanding ASP.NET View State
By default, dynamic web pages do not keep their state. For example, you set a value for a variable in the page load event of asp.net page. You want to increment this variable when user clicks button. This is not possible because at every page postback, the variable is created and the page load event is executed therefore, the variable is set to the initial value. Then, you need a way to keep the value of variable even if page postback occurs. Viewstate can be used to solve this problem.