ASP.Net viewstate questions on form postbacks - asp.net

Let's assume I have a very simple form, with a submit button and a dropdown list. When I change the list entry and hit submit, at what stage in the postback processing does the viewstate reflect my changed list entry?
According to O'Reilly's Learning ASP.Net 3.5, there are two loads taking place-- one before form validation and another after (diagram on page 266 for those with a copy).
According to the diagram the viewstate is loaded during the first load stage, before the validation. I assume my changed dropdown is reflected at this point?
Also, according to the diagram, posted data is processed twice, both before and after validation. Could anyone elaborate a little more on this, and what form processing takes place at each point?
Thanks for the help. It's a little misty, what takes place when and I'm trying to clear it up a bit.

The viewstate is loaded after page initialization but before page load. Validation takes place just before the event triggers for the button that caused the validation.
ASP.NET Page Life Cycle Overview
Understanding ASP.NET View State
ASP.NET Validation in Depth

Related

Understanding ViewState and FormData

I just got started with ASP.NET MVC, and I suddenly asked myself: why does ASP.NET need ViewState in the first place? FormData is actually holding the state across postbacks. ViewState is only needed if the state of the control is changed, and that change is NOT included in FormData. For example, what if the event handler changed the control's font color?
Two questions:
For WebForms, is that the reason for the need of ViewState?
If yes, how can MVC "maintain a control's property which is NOT in FormData"?
MVC and WebForms are very different in this regard. The point of WebForms was to help ease WinFroms developers in to web development. For that reason the infrastructure of WebForms simulates statefullness whenever it can. ViewState is one of the ways this is implemented. Since the browser only posts back form fields, in WebForms the entire page is one big form and the entire page is posted to the server. The ViewState is a hidden field, which holds everything BUT the data in the inputs, selects, etc. which the browser posts by default.
On the other hand MVC does not try to simulate statefullness. It works more directly with HTTP and the basic rules of a stateless system. So when you post a form ONLY the data in the inputs, selects, etc. gets posted. Nothing else makes it back to the server.
This is why, if you want to return the same view after a post with the updated data, you have to refill the ViewModel with data like you did in the original get method. MVC does not take care of this for you like WebForms.
Regarding why View State in first place, your explanation is related. View State is used to persist state across Post Backs and mainly to handle properties updated programmatic for example page with label and button and you have event handler for the button that change the label front color to red , in the page load the controls initiate the label with default color however when the button click it change the label color to red and keep that change in the view state so if anything triggered post back then after loading the controls in the page load it sets the front color to the value already saved inside the viewstate
For more details please check the following link http://msdn.microsoft.com/en-us/library/ms972976.aspx#viewstate_topic3
MVC doesn't have viewstate, MVC is based on model binding so when a form is posted MVC framework read the httprequest parameters and try to create strongly typed object from that request and you can create your own model binder that tell the MVC how to read the http request

FindControl won't find my dynamically added UserControl

I'm working on a project where the page load certain controls depending on the index available. The loading occurs in the page load where the method PopulateSearchField is called.
Within this method, all the UserControl are added on the page using : Page.LoadControl("path");
The page load and all the required controls are on the page. My problem is when the user click on the Search button the event is triggered and a query is built based on the user input int those controls. Unfortunately, the method isn't able to produce a proper query as it is unable to find any of the controls on the page.
With a temporary ControlCollection variable, I've been able to see that the number of controls on my page is 3 when it should be something from 4 to 10. Those 3 controls in the collection are the static label and buttons on the page.
I don't know if something is wrong with the code or if it's a page cycle problem as this solution used to work on framework 1.1. Yeah, I know this isn't the best thing to do so, but they did it this way and I gotta make it work.
I'm not sure if it is the migration that has caused the problem or not.
Thanks a lot, David!
When you click the button, the controls are no longer available server side when your click handler is being processed. The page, server side, has no knowledge of the controls you created dynamically since there are no server side controls for the posted values to map to. If you want to find the values, you need to inspect the posted control data and not rely on the server side asp.net control heirarchy.
You could also write all the data you require to a hidden field via javascript and then read the hidden data server side since it will will be posted.
The following is occuring:
Creating controls dynamically
Posting controls data on click
ASP.NET maps the data to the existing controls it knows about.
Your controls are not found so the data is no mapped to anything.
You need to add your controls before the mapping occurs (in PreInit). Check out the Page Lifecycle and you will see how it ties all the controls and data together.
Are you re-adding the controls to the new page when the user clicks search?
Remember... every time the user hits your server for that page... a new Page object is created. If you're dynamically adding controls, you have to do it every time the page loads.
Additionally, since you seem to want to get values out of the controls, you're going to have to make sure that the controls are created with the exact same ID property every time, and created before viewstate is loaded, if you want them to retain their values.

What are the main differences of defining a control statically or creating it dynamically on page load?

I am working on a project which creates controls dynamically for a form in the page_load event, loads in their current values from the database and saves their values (using FindControl) when the user clicks the continue button.
When I added a control statically in the .aspx page and followed their same procedure of loading the value in the page load and saving it on the button press I found that the value would not save correctly. It seems that it wouldn't save because the click event fires after the page_load, so the page_load of the post back reverted the value and the user entered value was not saved.
The strange thing is that by changing the control to be dynamically created just as all the other controls on the page and keeping the loading and saving the same it now works. Even though the page load still creates the control with the old database value.
It seems like a very fundamental asp .net feature here but i'm just unclear as to what is going on. I suspect it is to do with the timing of creation and maybe when the view state kicks in.
Static page controls are created just like dynamic page controls. The difference might be coming in your Page_Load. Whenever you postback all the controls are created afresh which means they are created with their initial values. This happens because after creating the controls asp.net throws away the controls/objects.
So, when the request comes, the first thing that asp.net does it to recreate the controls by looking at their definitions (in the designer files). On each postback they are created and initialized again losing their state in the process.
But after creating the controls Asp.Net loads any viewstate that is sent along with the request which makes people think that the state is always saved at the server.
What might be happening is that either the viewstate is not enabled for your control (in case they are created in designer), in which case you may try using EnableViewState property to true of the control.
Or, when you're doing a Page_Load, you're forcefully re-initializing everything. And in process losing all the control data. If you could post the logic of Page_Load, it might get clarified.
Make sure that:
you are not setting the value again for the static control in Page_Load. The dynamic control are probably getting around it by grabbing the ViewState and form values at a different stage in the lifecycle.
The dynamic controls are added After the static control. Or at least they are added in a different container. Placement in the control's collection can affect the ViewState, although it doesn't look like your scenario / since what you mention seems to be more about the values in the current post.
The save is happening After the Page_Load in response to the corresponding event.
I've run into similar problems in the past (quite a few times actually), but what helped me the most is understanding the ASP.NET Page Lifecycle.
Microsoft has an article on it which describes it pretty well, but this post by Solomon Shaffer really cleared up everything.
I suggest reading them both and coming back with additional questions regarding to a particular state, when to load/save data etc..
Hope this helps.
Marko
Note that you may want to use Page.IsPostBack property to avoid reinitializing values on button clicks and other events.
private void Page_Load()
{
if (!this.IsPostBack)
{
// Assign values to the controls.
}
}

Rebuild whole page on callback?

In asp.net is it a requirement to rebuild the whole page during every callback? For example my web page is split into three distinct areas and I have an update panel for each area. Lets say I want to update the third area, do I have to bother with any processing of the other two areas?
For example lets say there is a grid view in area two. The update panel in area three callbacks to update its content. Do I have to rebind the grid in area two?
Thanks,
AJ
Yes, this is how ASp.NET is done. If you use an updatePanel / AJAX partial update, you may get away building only part of the page. But then, your viewstate may be a problem.
What you see is basically one of the disadvantages of the ASP.NET model.
By default, "UpdateMode" is set to "Always" for UpdatePanels which means they update whenever anything "happens" on the page.
Try setting "UpdateMode" to "Conditional" for all your three UpdatePanels and see if that helps. (FWIW this is standard practice for me as part of writing the UpdatePanel definition. If you need to update an UpdatePanel when something happens on a different part of the page, you can use Triggers or update it with .Update() in code behind)
bgs264
Edit
I think I misunderstood your question originally; my suggestion above may improve page rendering times as partial postbacks result in less code being sent back and forth between client and server.
But yes as per other answer, all the controls have to go through their lifecycle (Init, Load, Render) on every page load / postback.

Tracking state using ASP.NET AJAX / ICallbackEventHandler

I have a problem with maintaining state in an ASP.NET AJAX page. Short version: I need some way to update the page ViewState after an async callback has been made, to reflect any state changes the server made during the async call.
This seems to be a common problem, but I will describe my scenario to help explain:
I have a grid-like control which has some JavaScript enhancements - namely, the ability to drag and drop columns and rows. When a column or row is dropped into a new position, an AJAX method is invoked to notify the control server-side and fire a corresponding server-side event ("OnColumnMoved" or "OnRowMoved").
ASP.NET AJAX calls, by default, send the entire page as the request. That way the page goes through a complete lifecycle, viewstate is persisted and the state of the control is restored before the RaiseCallbackEvent method is invoked.
However, since the AJAX call does not update the page, the ViewState reflects the original state of the control, even after the column or row has been moved. So the second time a client-side action occurs, the AJAX request goes to the server and the page & control are built back up again to reflect the first state of the control, not the state after the first column or row was moved.
This problem extends to many implications. For example if we have a client-side/AJAX action to add a new item to the grid, and then a row is dragged, the grid is built server-side with one less item than on the client-side.
And finally & most seriously for my specific example, the actual data source object we are acting upon is stored in the page ViewState. That was a design decision to allow keeping a stateful copy of the manipulated data which can either be committed to DB after many manipulations or discarded if the user backs out. That is very difficult to change.
So, again, I need a way for the page ViewState to be updated on callback after the AJAX method is fired.
If you're already shuffling the ViewState around anyway, you might as well use an UpdatePanel. Its partial postbacks will update the page's ViewState automatically.
Check out this blog post: Tweaking the ICallbackEventHandler and Viewstate. The author seems to be addressing the very situation that you are experiencing:
So when using ICallbackEventHandler you have two obstacles to overcome to have updated state management for callbacks. First is the problem of the read-only viewstate. The other is actually registering the changes the user has made to the page before triggering the callback.
See the blog post for his suggestions on how to solve this. Also check out this forum post which discusses the same problem as well.
I actually found both of those links you provided, but as noted they are simply describing the problem, not solving it. The author of the blog post suggests a workaround by using a different ViewState provider, but unfortunately that isn't a possibility in this case...I really need to leave the particulars of the ViewState alone and just hook on to what is being done out-of-the-box.
I found a fairly elegant solution with Telerik's RadAjaxManager. It works quite nicely. Essentially you register each control which might invoke a postback, and then register each control which should be re-drawn after that postback is performed asynchronously. The RadAjaxManager will update the DOM after the async postback and rewrite the ViewState and all affected controls. After taking a peek in Reflector, it looks a little kludgy under the hood, but it suits my purposes.
I don't understand why you would use a custom control for that, when the built-in ASP.NET AJAX UpdatePanel does the same thing.
It just adds more complexity, gives you less support, and makes it more difficult for others to work on your app.

Resources