I have a textbox and button on my .aspx page. The EnableViewState property of the textbox is set to false. But when I enter some text in the textbox and click the button the entered text is still present in the textbox. I expect the textbox to be blank since EnableViewState is set to false. Am I missing something?
Please check this Code Project article to better understand ViewState and Postback Data.
It is something like :
Why some controls retain values
even after disabling the ViewState
while others do not?
The answer is Controls which
implements IPostBackEventHandler IPostBackDataHandler like
Textbox, Checkbox, etc. will retain
the state even after disabling the
viewstate. The reason is during the
Load Postback Data stage, these
controls will get state information
from Posted back form.
But controls like label which do not
implement IPostBackEventHandler IPostBackDataHandler will
not get any state information from
posted back data and hence depend
entirely on viewstate to maintain the
state.
Below is related paragraph to your question.
In page life cycle, two events are
associated with ViewState:
Load View State: This stage follows the initialization stage of
page lifecycle. During this stage,
ViewState information saved in the
previous postback is loaded into
controls. As there is no need to check
and load previous data, when the page
is loaded for the first time this
stage will not happen. On subsequent
postback of the page as there may be
previous data for the controls, the
page will go through this stage.
Save View State: This stage precedes the render stage of the page.
During this stage, current state
(value) of controls is serialized into
64 bit encoded string and persisted in
the hidden control (__ViewState) in
the page.
Load Postback Data stage: Though this stage has nothing to do with
ViewState, it causes most of the
misconception among developers. This
stage only happens when the page has
been posted back. ASP.NET controls
which implement IPostBackEventHandler IPostBackDataHandler
will update its value (state) from the
appropriate postback data. The
important things to note about this
stage are as follows:
State (value) of controls are NOT retrieved from ViewState but from
posted back form.
Page class will hand over the posted back data to only those
controls which implement
IPostBackEventHandler IPostBackDataHandler.
This stage follows the Load View State stage, in other words state of
controls set during the Load View
State stage will be overwritten in
this stage.
This is by design
The following server controls persist their information across requests even when the control ViewState (the EnableViewState attribute) is set to False:
* The TextBox control.
* The CheckBox control.
* The RadioButton control.
This behavior occurs because the ViewState of a control is only one of the methods that are used to persist a control's attributes across requests. In the server controls that are mentioned in the "Symptoms" section, attributes that are not normally posted to the server through the form-get or the form-post are handled by the ViewState. These values include attributes of the control, such as BackColor. Attributes that are normally posted to the server are handled by the IPostBackDataHandler interface. An example of such an attribute is the checked attribute of the CheckBox control.
Also read this article
ASP.NET: TextBox and EnableViewState="False"
For understanding of Viewstate I don't think there is a better article than MSDN
Understanding ASP.NET View State
Take a look at Server controls persist their state when EnableViewState is set to False
The following server controls persist their information across requests even when the control ViewState (the EnableViewState attribute) is set to False:
The TextBox control.
The CheckBox control.
The RadioButton control.
This behavior occurs because the ViewState of a control is only one of the methods that are used to persist a control's attributes across requests. In the server controls that are mentioned, attributes that are not normally posted to the server through the form-get or the form-post are handled by the ViewState. These values include attributes of the control, such as BackColor.
Attributes that are normally posted to the server are handled by the IPostBackDataHandler interface. An example of such an attribute is the checked attribute of the CheckBox control.
Example: Consider backcolor setting programmatically. On postback, if viewstate is switched off, the background color of the Textbox control is lost. However, the text value of the control is maintained.
Note: If the backcolor was set directly in markup rather than in code behind, it would have persisted.
<form id="form1" runat="server">
<asp:TextBox ID="Textbox1" runat="server" EnableViewState="false"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" EnableViewState="false" />
</form>
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.Textbox1.BackColor = Color.Yellow;
}
}
Following is from Understanding ASP.NET View State:
It is a common misconception among developers that view state is somehow responsible for having TextBoxes, CheckBoxes, DropDownLists, and other Web controls remember their values across postback. This is not the case, as the values are identified via posted back form field values, and assigned in the LoadPostData() method for those controls that implement IPostBackDataHandler.
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.
Also refer following
View State for TextBox and other controls that implement IPostBackDataHandler
How do I disable viewstate for a specific control?
Related
I'm adding dynamic controls to a page based on data from a database to generate RadioButtonList questions.
Sometimes the questions are required, in which case after the data is retrieved from the database and the RadioButtonList is populated, I dynamically add a RequiredFieldValidator for the RadioButtonList.
The problem arises on postback, when in Page_Load() I execute Page.Validate() which always fails. I discovered that this is because the controls are being re-added on post-back but they aren't repopulated with the user's responses.
My question is:
When can I grab the user's response once they click "Submit", where do I store it, and what's the best way to bring it back so that Page.Validate() validates against controls with the proper responses?
Instead of creating the validation controls in Page_Load (or in a function that's called from within page_Load) do so in Page_Init
For more info see the Page Lifecycle:
In the Page Lifecycle, putting it in Page_Init allows the controls to be created on each page load, but BEFORE the viewstate values are applied. This means that the controls are created, and then the user selection is applied.
If you have it in Page_Load, then the controls are created AFTER the Viewstate values are applied. This means that the controls are just created from scratch after the viewstate has been applied, resetting everything to the default value.
Actually, this page says it better:
During page initialization, controls on the page are available and
each control's UniqueID property is set. Any themes are also applied
to the page. If the current request is a postback, the postback data
has not yet been loaded and control property values have not been
restored to the values from view state.
During load, if the current
request is a postback, control properties are loaded with information
recovered from view state and control state.
Use Page_Init when you
have to create controls dynamically. The controls are created every
time that the page is run. The best place to do this is in the
Page_Init function.
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'm learning about ASP.NET, mainly by following through a book, but also making an effort to actually do things along the way. But, I came across an explanation about list controls which I don't understand. This is what it says:
"[in the context of the Smart Tasks panel]...the last option sets the AutoPostBack property of the control. With this option checked, the control will submit the page it's contained in back to the server as soon as the user chooses a new item from the list"
Can you explain this statement for me? Thanks in advance for your help.
For normal client controls (such as a list control with AutoPostBack set to false), when a user chooses an item in the list, the browser does not communicate with the server. There's no network traffic and no delay for your user before they see the results of the choice, but there's also no opportunity to do anything in your server code, like calculate dependent values. If you want to do anything to the screen in response to the choice, you have to use a client-side script.
When AutoPostBack is set to true, selecting an item in the list sends a message to the server (via an HTTP POST). ASP.NET then executes whatever code you have attached to the list's changed event, rebuilds the page, and sends the revised page to the client.
If you set AutoPostBack="true" on a control, when it's value changes, it will automatically postback to the server.
For example if you wanted a dropdown that when changed displayed different data in a table below or something, you might want to postback get the new value so your page could refresh the data.
This is opposed to style of the dropdown and a button beside it you click to postback, so instead of change value, click the button, you can just change the value with AutoPostBack="true".
A ListBox has a SelectedIndexChanged event that you can handle to detect when the selected item in a ListBox has changed. You'd configure it like this:
<asp:ListBox ID="ListBox1" runat="server" OnSelectedIndexChanged="ListBox1_SelectedIndexChanged"/>
protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
// Do something
}
With AutoPostBack="false" (the default), that event handler doesn't actually happen on the server in "real time". The user has to perform an unrelated action to submit (POST) the form, such as clicking a button, to make that event fire on the server.
If you want to take "real time" action on that event, you set AutoPostBack="true" which makes the form automatically submit every time the selected item is changed.
The benefit - you get "real time" notification of events. The drawback - the page talks a lot more to the server, so each click costs bandwidth and causes client "lag".
Further reading: http://www.dotnetspider.com/resources/189-AutoPostBack-What-How-works.aspx
When a user selects a ListItem (or whatever the collection item is), the page should automatically submit the web form to the server with a POST event.
here's the wikipedia page on HTTP POST events
http://en.wikipedia.org/wiki/HTTP_POST
The responsibility of an asp.net control contained in a Page is to render a part of the html that the user will end up seeing in his browser. Some controls support the AutoPostBack property. What it does is that it makes the control emit some extra javascript that will submit the form whenever the value of that control is changed, so that you can react to this on the server side.
Basically AutoPostBack is used so that whenever there is some change in the controls text or anyother change in the controls property, the page is submitted to the server.
Posting the page means, the page is submitted to the server. Suppose i use a textbox and i make its AutoPostBack = "true", now i write some text into it and click outside the textbox, then the page will refresh.
This refresh indicates that your value which you entered into the textbox has been submitted to the server.
The postback is handled by ASP.NET server. AutoPostBack will automatically post back your page to the server.
Add an event Handler. This will give you a better picture.
In your case of DropDownList: Add an eventhandler: double click the DropDownList, it will route you to an eventhandler:
Write something in that event handler let us say : Response.Write("message");
The page will refresh and you will see your message, this means the page was posted to the server and the server has executed your event handler and displayed you the message.
I hope this was usefull
We have created a control that needs to persist data via the ViewState property of the Control class. Our class subclasses control strictly to get access to the ViewState property (it's protected on the Page object). We are adding the control to Page.Controls in OnInit, and then attempt to set the ViewState property in OnPreLoad.
When we decode and examine the ViewState of the page, our values have not been written out, and are thus not available for later retrieval.
Does anyone know how we can get our control to participate in the ViewState process?
The issue is adding the control to the Page directly. Unfortunately this is too high up the controls hierarchy to participate in the Forms ViewState Handling. If you add the control onto the actual ASPNet Form's Controls collection somewhere then it will successfully participate in LoadViewStateRecursive and SaveViewStateRecursive.
Try creating your control in OnInit, then add it to the Page.Controls during OnLoad.
ViewState isn't loaded until after OnInit, but before OnLoad.
Here's a rough outline of the Page Life-Cycle(GregMac) posted this in a response to an earlier question of mine.
Initialize
LoadViewState
Load Postback Data
Call control Load events
Call Load event
Call control events
Control PreRender
PreRender
SaveViewState
Unload
I am adding some user controls dynamically to a PlaceHolder server control. My user control consists of some labels and some textbox controls.
When I submit the form and try to view the contents of the textboxes (within each user control) on the server, they are empty.
When the postback completes, the textboxes have the data that I entered prior to postback. This tells me that the text in the boxes are being retained through ViewState. I just don't know why I can't find them when I'm debugging.
Can someone please tell me why I would not be seeing the data the user entered on the server?
Thanks for any help.
This is based on .NET v1 event sequence, but it should give you the idea:
Initialize (Init event)
Begin Tracking View State (checks if postback)
Load View State (if postback)
Load Postback Data (if postback)
Load (Load event)
Raise Changed Events (if postback)
Raise Postback Events (if postback)
PreRender (PreRender event)
Save View State
Render
Unload (Unload event)
Dispose
As you can see, the loading of ViewState data back to the controls happen before the Load event. So in order for your dynamically-added controls to "retain" those values, they have to be present for the ASP.NET page to reload the values in the first place. You would have to re-create those controls at the Init stage, before Load View State occurs.
I figured out yesterday that you can actually make your app work like normal by loading the control tree right after the loadviewstateevent is fired. if you override the loadviewstate event, call mybase.loadviewstate and then put your own code to regenerate the controls right after it, the values for those controls will be available on page load. In one of my apps I use a viewstate field to hold the ID or the array info that can be used to recreate those controls.
Protected Overrides Sub LoadViewState(ByVal savedState As Object)
MyBase.LoadViewState(savedState)
If IsPostBack Then
CreateMyControls()
End If
End Sub
I believe you'll need to add the UserControl to the PlaceHolder during the Init phase of the page life cycle, in order to get the ViewState to be filled in by the Load phase to read those values. Is this the order in which you're loading those?
Ensure you are defining your dynamic controls at the class level and adding them to the ASP container:
Private dynControl As ASP.MyNamespace_MyControl_ascx
And when you instantiate the control, ensure you call LoadControl so the object is added properly:
dynControl = CType(LoadControl("~/MyNamespace/MyControl/MyControl.ascx"), ASP.MyNamespace_MyControl_ascx)
You have to create your controls in the Page_PreInit event handler. The ASP.NET server control model is tricky; you have to fully understand the page lifecycle to do it right.
As others have said, any form of control manipulation must be done before viewstate is created.
Here is a good link on the page lifecycle to help you out:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
We have experienced the same thing and have handled it by using ghost controls on page_load that have the exact same .ID and then the post back picks up the events and the data. As others said it's the dynamic adding of the control after the init stages that the state is built already and controls added after aren't stored.
Hope this helps a bit.
I also want to add that I've seen user controls work the way that you'd expect them to just by setting the Control.ID property at run time. If you do not set the ID, items may get built in a different order and work oddly.