view state in ASP.NET MVC Application - asp.net

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

Related

Google App Maker Widget Validate on Datasource select

I have three different fields/textbox widgets, that rely on querying the same data source to be checked to avoid duplication. For reasons, I do not want to turn on the unique/required for those three fields.
I put some code to check for validation. My problem is that when I call the form's validate function, it takes some time till the validation comes back with an error message. However the form's validate returns immediately and allows people to click Submit.
How can I avoid this problem?
Block till validation kicks (setTimeout function?)
Set a separate invisible field such as working and set the validationError on the field and clear after validations clear? This will probably be a numeric field so that I can wait for all streams in parallel to finish.
Final question. is Validate a blocking function as it goes through the fields? I am guessing Yes.

What exactly does control state do in textbox and other controls

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.

Tracking down error on form or in session

Apologies if this is classic ASP 101, but its been so long since I did any ASP Im struggling to understand / track this error down. What makes it worse is Ive inherited this application and I cant ask the original author..
I have a shopping cart that includes an input checkbox and numerous other fields. When the form is processed and submitted it is run through some javascript and then if all is ok, redirected to another page. (Nothing unusual there). Firebug shows that at this point the value of the check box is different depending on its checked state.
When the form is submitted it goes to another page that iterates over the session.Contents() collection, and builds up a string that is sent to a 3rd party. Using fiddler, it appears that whilst the name of the checkBox is in this string, the value is always 'on'
From reading Google, I see that the session.Contents collection is all parameters that have been placed in the session / application. but a grep across all the files in the project directory doesnt turn up anywhere that the checkbox is added to the session.
So, is the cb there simply because it is on the form or used in javascript, or are there other ways of adding the variable into the session. (Grep on the name doesnt turn up any other instances).
And secondly, if the variable is in the session, no matter how it got there, why is it always set to "on". Im assuming that somehow it has been added to the session and set to On before the form is processed. But the checkbox defaults to unchecked, so Im confused!
Can anyone help explain this, or even suggest how I can track it down / fix it. (The obvious answer is to try to force it into the session with the correct value, but I'd like to know why it is misbehaving rather than just ignore it in case I meet something like this again!
Thanks
I am going to assume that you have already determined that the JavaScript is not modifying checkbox state priort to allowing the submission.
When your form is submitted, the fields that are submitted are in the Request.Form collection. When a checkbox is not checked, it is not part of the Request.Form collection. Therefore, there will be as many checkbox fields in your Request.Form collection as you had checked when submitting, and they will all have the value of their respective "value" property.
If you then add these to the Session.Contents collection, they persist until the session ends. If you never explicitly clear the Session.Contents collection, but submit the form more than once with different values, then the Session.Contents collection will continue to accrue more and more (checkbox_name, checkbox_value) pairs until such time as it contains a (checkbox_name, checkbox_value) pair for every checkbox on your form.
You may wish to write a function that clears each one of your form fields from the session, and call this either after processing a form, or before processing a form (whichever makes sense for your application). Alternatively, just use the Request.Form collection.

Retain Dynamic dropdown values

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];

Why input elements don't render the value passed in ASP.Net MVC?

This post asks this question but doesn't really give an answer, so I thought I would ask the question differently.
I have a page that renders a hidden value from the model:
<%=Html.Hidden("myName", model.myValue) %>
Since I am passing a value in the value parameter, you would think it would output that value, but it doesn't.
The code for rendering input fields has the following:
string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string));
tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : valueParameter), isExplicitValue);
Basically, if the ModelState (which contains posted values) contains a value for the "name" passed, it will use that value instead of your passed value to the helper method. In my case, I updated the model and my updated value wasn't outputted.
If I pass a value to a method, I expect that value to be rendered.
Am I missing something in this design or is it just wrong?
This is by design. Here is the intended flow:
The user requests a certain URI.
Your controller builds out a model.
The view is rendered. The ModelState dictionary should be empty at this point, so the value you pass to Html.Hidden will be rendered. However, the feature in question is more directly related to user input, so consider the case of Html.TextBox("someName", Model.SomeValue)
Now imagine the user enters some invalid data. If you have a client-side validation, this would be caught before the POST, but let's pretend you don't, or that the user has somehow circumvented it.
In this case, the action which handles the POST will return a ViewResult, causing the view from step 3 to be re-rendered. However, the user will see the value they input (so they can fix it) instead of the value from your model object. The idea here is that the data the user entered possibly cannot be represented as a value in Model.SomeValue, due to type safety. If Model.SomeValuewas of type integer, for example, and the user entered "ABC", the only way to re-render the user's data is to put it somewhere else. And that "somewhere else" is ModelState.
Re-displaying the user's invalid data allows the user to fix the data they entered and re-post the form.

Resources