I want to know about the similarity of the control state and ipostbackdatahandler.
I have disabled view state, then also value of text box in retained in it, why does this happen? Is it because of control state or "i post back data handler" interface.
if it is because of control state then please explain why.
How View State works?
If View State is on for any control, during LoadViewstate, the View State data that got saved last time , gets populated in the control. And in last, the SaveViewState method of every controls that are part of the control hiearchy, gets called and combined View State of all the controls gets base64 enocoded and saved.
So as we know the page is recreated every time page makes a trip to the server, the data persistence is adone with the help of viewstate.
even if we set off the View State of some controls like textbox, checkbox etc.. the data persists during postback. i.e., whenever a page is submitted or posted back to server, the entire form data is posted to the server as a collection with the request. The collection is in the form of NamedValue collection and this collection has the mapping with uniqueid of the control and the value of the control. You can read the data from the form collection by using the following code snippet
//Reading textbox value from the form collection
string textboxvalue = Request.Form[textbox1.UniqueID];
ASP.NET uses this primitive to update the control’s value. ASP.NET uses IPostBackDataHandler for the controls that load the data from the form collection.
Actually all the controls which implement IPostbackdatahandler, implement the method LoadPostData and RaisePostDataChangedEvent. But here the key method is LoadPostData, which returns true if the posted value is changed from earlier value and updates it with posted value, else it returns false. Lets see the sample code here
public virtual bool LoadPostData(string uniqueId,
NameValueCollection postedCollection) {
//Getting the current value of control
String currentValue = this.Text;
//Getting the posted value from the form collection
String postedValue = postedCollection[uniqueId];
//Checks whether the posted value is changed from the current value, if yes updates it with the posted value and return yes
if (currentValue == null || !currentValue.Equals(postedValue)) {
this.Text = postedValue;
return true;
}
//else return false
return false;
}
As from the Page Life Cycle, we can see LoadPostData is called after the LoadViewState, whether viewstate is on or not, it gets populated from the posted data. That’s why the data get persisted even if viewstate is set to off for few controls. Following is the complete list of the controls, those implement IPostBackDataHandler.
CheckBox
CheckBoxList
DropDownList
HtmlInputCheckBox
HtmlInputFile
HtmlInputHidden
HtmlInputImage
HtmlInputRadioButton
HtmlInputText
HtmlSelect
HtmlTextArea
ImageButton
ListBox
RadioButtonList
TextBox
Source
ViewState is a messy hack to persist data between requests. The web is stateless and ViewState tries to make it appear stateful.
I believe the TextBox (and other <input/> controls) keep their value without ViewState because their values are POSTed in a form, while Label (<span/>) values are not.
Many Web Forms developers that care about page size will disable ViewState globally and only enable it for specific controls. If you use standard paging in a GridView, for example, you will need ViewState so that ASP.NET knows what page number the user clicked. You could use custom paging and use actual links for the page numbers and then turn on off ViewState.
Related
Good afternoon, I have an ASP.NET web page and I created a user control that has some properties that I need to always be retrievable.
ViewState was added to keep information, but the drawback now is that when adding the same control on the same asp.net page and from within a function of the control I want to retrieve the value of the property, this will retrieve the last value entered in the ViewState .
Beforehand thank you very much.
<PersistenceMode(PersistenceMode.InnerProperty), TemplateInstance(TemplateInstance.Single)>
Public Property GuardadoTemporal() As Boolean
Get
If ViewState("GuardadoTemporal") Is Nothing Then
Return false
Else
Return CBool(ViewState("GuardadoTemporal"))
End If
End Get
Set(ByVal value As Boolean)
ViewState("GuardadoTemporal") = value
End Set
End Property
example for use
Use SaveControlState and LoadControlState https://learn.microsoft.com/en-us/dotnet/api/system.web.ui.control.savecontrolstate?view=netframework-4.8
This will save it into the controlstate for each control so you don't get user controls clobbering each others data. controlstate can't be turned off either
I have 3 dyanmically generated dropdowns in this aspx page. The 2nd and 3rd one are populated as per the selected value of the first one (I've the code for creating the 2nd and 3rd dropdown in 1st one's selectedindexchanged event)
How do I write the code in a such a way that when I traverse back to the page, the dynamic dropdowns retain their selected values?
I'm assuming that what you mean when you say that you "traverse back" to the page is that you navigate to a different page on the site and come back to this page that it's dropdown values will be filled in with what the user selected.
Remember that HTTP is an inherintly statless protocol in that it won't remember data in between postback to the servers. In order to overcome this limitation ASP.NET and other web frameworks use various ways of saving data between request. Currently you are relying on "ViewState" that is stored within the page as a hidden variable called __VIEWSTATE (look at the page source sometime to get an idea of what field looks like) this scope of this hidden variable is when the page first gets loaded and everytime you do a postback to the same page. From your description you probably need a longer term persistance called SessionState or Cookies that will store values for a particular Session.
Here is a link from MSDN that contains interesting information regarding all the possible ways of saving state in an ASP.NET application. Let me know if you've got any other questions.
http://msdn.microsoft.com/en-us/library/75x4ha6s.aspx
--EDIT--
Here's a link to the MSDN article on Session State. My recommendation is to be careful with Session state and only store things that are absolutely required. Also I'd recommend you have a Class that contains the a bunch of constant for the Session Keys. It's easier to manage
http://msdn.microsoft.com/en-us/library/ms178581.aspx
ie instead of
string value = Session["Key"];
//Create a class SessionKeys
Class SessionKeys{
public const string SESSION_KEY = "Key"
}
//Now that string is strongly typed and you don't have to worry about misspelling it
string value = Sesssion[SessionKeys.SESSION_KEY];
Assuming I have access to the object that would be databound, and the settings for the databinding DataField, FormatString, etc...
How would I programattically get the resulting string value of a databinding without actually databinding to a control?
Context: This is in the overloaded InitializeCell event of a Telerik (Telerik.Web.UI) GridDropDownColumn that I am inheriting. I want to cache the resulting string value, but I need the value before the normal databinding event fires.
Just do a separate database query early in the page life cycle (pre-init) and cache the value manually...
I'm designing/building a medium-scale ASP.NET web application using WebForms. The main work in the project is building each web form, and I don't know how to design (in a code/data/data flow sense) my controls.
I'll give you a few examples of what I'm dealing with so you can understand what I mean:
A common task in the application is the entry and display of street addresses. So I created a UserControl called "AddressFields" that contains a series of HtmlInputText elements (one for line 1, another for the town/city, country, postal code, etc). My DB entities classes contains a class called "Address" so this control has the methods:
void ShowAddress(Address addr) - which fills the HtmlInputText elements with the appropriate text).
void UpdateAddress(Address addr) - which updates the contents of addr with the current contents of the HtmlInputText elements
Address CreateAddress() - which creates a new instance of Address and then passes it into UpdateAddress and then returns it
So far, so good. This works because the AddressFields control is 'dumb' all it does is display and retrieve data to the user. ViewState is managed by the HtmlInputText fields directly too, so no additional logic is required.
Another entity in my application is the "Client" which is a class with an Address attribute, but this class also has a few more complicated aspects. For example a Client has a series of tags ('categories' in my application) that can be assigned. In this case, I designed a subclass of the ASP.NET CheckboxList control.
I created another UserControl called "ClientFields" which contains all the necessary fields to display a Client's information (including an AddressFields control), but it also includes my CheckboxList subclass called "CategoryList".
The problem here is that the CategoryList control needs to be supplied to the data to display (but not on postbacks, since it uses viewstate). In this case, my question is: whose responsibility is it to connect to the database and retrieve the category listing?
Is it the CategoryList control? (If so, where in the control lifespan does it query the database? It can't do it in Control.Load because that occurs after the ClientFields has been populated. Does it occur in ClientFields itself? (again, then where in the lifespan does it happen, because ClientFields has its ShowClient(Client c) method called within Page.Load. An alternative is to expose the CategoryList from the ClientFields so it can be accessed directly by the Page, but that's a violation of good software design.
In my opinion, CategoryList is responsible to retrieve the category listing data because all of category data should be retrieved no matter if one or more of them are selected by a particular client.
when does CategoryList query the database in its lifespan?
Generally, override OnInit method to populate the CategoryList, but ViewState doesn't begin to work at that time, so you have to retrieve the data from DB and populate itself on each postback. If you'd like to rely on ViewState, define and register the InitComplete event handler of Page on overrided OnInit method and populate the CategoryList in the event handler. Both OnInit method and InitComplete event are called/fired before Load event.
//In CategoryList control
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page.InitComplete += new EventHandler(Page_InitComplete);
}
void Page_InitComplete(object sender, EventArgs e)
{
// retrieve the data and populate the control
}
Hope it helps
I have read that viewstate is not there in asp.net MVC application.
I am doing model validation. Now if i have two text boxes on my page,and i am doing required filed validation for both of them in model. This validation is done on server side on click of a button. I will fill one text box and click on submit button. It does the validation and returns the result saying second field is required. At this time value of the first text box is retained. So can you tell me how this text box is retaining the value even after postback?
There is no "postback". There's just a post.
Server returns HTML.
Browser renders it.
User POSTs crap data.
All of the user's submitted data is saved in the Controller.ModelState collection.
Each ModelState entry has its Errors property set if there is a validation error.
Server looks at crap data. Returns page same as (1) except that it includes user's submitted data, good or bad, and validation errors for the crap data.
Browser renders that.
When you call, say, Html.TextBox("someName", someValue) then the text box will contain someValue unless there's a ModelState key for "someName", in which case the value from ModelState is used instead. This is how the default data (if any) is displayed originally, but the user's data is displayed after an error.
Read about ModelState. When you post http form, values are stored in ModelState object and reused when you generate form again using html helpers (Html.Label, Html.Hidden, Html.TextBox).
Form is shown using Html.TextBox().
User enters value first time.
Form is posted.
ModelState object holds textbox value.
Form is shown second time using Html.TextBox() again. Method looks into ModelState and sets its value again as it was posted first time. Even if you provide new value, it will be searched in ModelState object.
View is rendered using Model. On failed validation if you pass the same model (with ModelState errors) to the view it will repopulate the same view with extra Validation messages which are rendered using ModelState Errors.
The value of the textbox is bound to the Model value.
Upon validation failure the page is redisplayed with it's Model in the state it was when the submitted (i.e. with a value for the first textbox) and any ModelState Errors added.
No viewstate coming in to play ;-)
Enabling view state is actually supposed to retain values of the controls if you are posting back to the same page