How to load a page with its default values after a postback - asp.net

I'm creating user controls that i will put into an update panel and make them visible only when required using triggers. Once visible it will float in a dialog box so it has a close button which will just hide the control on client side.
The controls have multiple post back states, like a wizard, i'm using a multi view control to accomplish that. My problem is that once the user is at step number two in the control, if the user closes the dialog, than opens the dialog again, (note that the control is made visible on the server and reloaded by updating the updatepanel) the second step will still be displayed. The reason is . because whenever there is a postback the control will load its state using the viewstate, even if EnableViewState is false it will still load it using the LoadControlState method. so my quesion is how can i force a user control to load fresh with its default values without any postback data.

We had a similar circumstance and the only way we found to reset our control was to do that in the code behind of the page. Not in an ajax call but on submit of the page because then we could set the properties and have them go into viewstate.
i'm pretty sure that that will break your design though.
Have you considered writing the page as RESTful? At least then you can ditch viewstate and read and write to a meaningful data store.
ViewState is probably the number one reason I went over to MVC and now avoid WebForms like the plague.

If its a wizard that uses a dialog and each step is required, dont have a close button.
If the user closes it you could refresh the whole page so the user has to start again?
I had so many issue like this with WebForms, where I was only using the UpdatePanel for ajax as it "looks" like an easy option. MVC sounds like a bit of a learning curve and it is, however you can acheive things by building pages with MVC and jQuery without MS ajax and the hassle of all the events in a page that constantly fighting with each other. Its difficult to make this step without knowing MVC and geetting your hand dirty, but its worth it.

Its is possible.
I found a secret method in the control class, called ClearChildState(), this is a protected method and will clear the viewstate and the controlstate for all childcontrols.
So in my example, i created a class that inherits from panel
namespace MyControls
{
public class Panel:System.Web.UI.WebControls.Panel
{
public void Reset()
{
ClearChildState();
}
}
}
In my page initialize event i check for request[flag] to reset the control
public partial class Test : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (!string.IsNullOrEmpty(Request["Reset"]) && Request["Reset"] == "1")
{
pnlCreateAccountDialog.Reset();
}
}
}
OnClient side i have a Reset() function that i can call whenever i want the next postback to load a clean control
<script type="text/javascript">
function AddReset() {
$('#Reset').val('1');
}
function RemoveReset() {
$('#Reset').val('');
}
</script>

Related

short string representing Viewstate Visible even if view state on each and every control is disabled

I disabled the viewstate on page and each control within it. But I still see short string representing the viewstate in the page source.
I created a page with two controls, one a checkbox and other a texbox. I completely disabled the viewstate for both the controls and the page. But I still see a div rendered which contains the viewstate in the hidden variable:
<div class="aspNetHidden"> <input id="__VIEWSTATE" type="hidden"
value="/wEPDwUKMTcwNTQzMjY4MWQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFG‌​
2N0bDAwJE1haW5Db250ZW50JGNoYm94VGVzdPRq7jJUwzyCcKYfAFB/seRcAvziSp3bKL23H9U7O9sU"
name="__VIEWSTATE"> </div>
Can anyone help in understanding this behaviour of asp.net
1) You must have a server-side form tag () in your ASPX page if you want to use ViewState. A form field is required so the hidden field that contains the ViewState information can post back to the server. And, it must be a server-side form so the ASP.NET page framework can add the hidden field when the page is executed on the server.
2) The page itself saves 20 or so bytes of information into ViewState, which it uses to distribute PostBack data and ViewState values to the correct controls upon postback. So, even if ViewState is disabled for the page or application, you may see a few remaining bytes in ViewState.
3) In cases where the page does not post back, you can eliminate ViewState from a page by omitting the server side tag.
http://msdn.microsoft.com/en-us/library/ms972427.aspx
It's the control state.
If you really want to get rid of viewstate and controlstate you can use this code in the code-behind for the page, or in any class that the code-behind derives from
class MyPage : Page {
private class DummyPageStatePersister : PageStatePersister {
public DummyPageStatePersister(Page p) : base(p) {}
public override void Load() {}
public override void Save() {}
}
private DummyPageStatePersister _PageStatePersister;
protected override PageStatePersister PageStatePersister {
get {
if (_PageStatePersister == null)
_PageStatePersister = new DummyPageStatePersister(this);
return _PageStatePersister;
}
}
// other stuff comes here
}
Be very careful when doing this, though, since you're violating the contract with the controls. MSDN explicitly states that control state is always available. In practice, however, it has worked for me.
Edit:
Since I was downvoted, I like to point out again: Don't do this unless you know exactly what you are doing. In my case, almost the entire application was written in client-side javascript, and on those few occations where postbacks occurred, I always used the Request.Form collection to retrieve the values. Do not use server-side controls for anything but simple rendering if you do this.
No, you can not get rid of View State completely. You will always have a relatively short string representing the page itself even if you turn off the view state on each and every control.
Check State Management (View State).

Showing a PopUp in an ASP.Net before Page_load

I am developing an ASP.net application in which i am supposed to show a select language Popup( a simple screen where user can select language) to the user when he logs in for the first time. I tried calling the PopUp from the InitializeCulture event but the PopUp appears after the home Page Gets loaded.
I want the PopUp to appear before the page is loaded. Once the user selects the language from the PopUp, i want the page to appear in that language.
I am using the following code the call the PopUp
Page.ClientScript.RegisterStartupScript(typeof(Page), "onload", script);
Have the user redirected to a select language page. Then redirect to the site afterwards. You can also check on page load to be sure a language has been selected or redirect to the page.
To provide some explanation of Chad's response, it helps to understand the core of the ASP.NET Page Life Cycle. In particular, when an aspx page is requested from the server for the first time (i.e. not a post-back), IIS recognizes the .aspx extension and hands it off to the ASP.NET engine for rendering. The ASP.NET engine first instantiates the code-behind class, executes any pre-render methods or events (Init, Page_Load, PreRender, etc.), and also processes all of the non-HTML markup ('<%...%>' and '') in the .aspx file. When all of this is done, it has the complete HTML page that is then returned to the browser in the HTTP response).
The point here is that the browser never sees any of your HTML, including the RegisterStartupScript code, until after your Page_Load or any other server-side code has already completed.
Another possible solution is to use a MultiView which shows the language selection UI in one View and the actual page content in another view. The language selection would now be done via controls directly on the page rather than in a pop-up. In your Page_Load, you check to see if a language has been selected and if not, show the first View. After the user selects their language, is submits a post-back to the server which calls the Page_Load a second time (this time with IsPostBack being true). You then set the language in your code based on the user's selection and switch to the second View that contains the main page content. You may also get a slightly better user experience by wrapping the MultiView in an UpdatePanel so you get AJAX post-backs, instead of full-page ones.
So the basic logic in your Page_Load would look something like this (using C# like syntax):
if (!IsPostBack) {
string userLang = SomehowGetSelectedLanguageFromUserProfile(); // You provide
if (String.IsNullOrEmpty(userLang) {
PopulateLanguageComboBox(); // You provide
multiView1.ActiveView = 0;
} else {
DoAnyWorkNecessaryToRenderPageInSpecifiedLanguage(userLang); // You provide
multiView1.ActiveIndex =1;
}
} else {
if (multiView.ActiveView == 0)
{
if (comboLangSelect.SelectedIndex <= 0) {
lblErrorMessage.Text = "You must select a language to continue";
lblErrorMessage.Visible = true;
} else {
DoAnyWorkNecessaryToRenderPageInSpecifiedLanguage(comboLangSelect.SelectedValue);
multiView1.ActiveIndex =1;
}
} else {
// Any other PostBack processing required for the main page.
}
}
Please note that I wrote this entirely here in the response box and have not compiled nor tested this in any way. It is only meant to provide you the general logic behind the solution I am suggesting.
If you really need to do the language selection in a pop-up, it can be done, but then you need to have the pop-up window communicate the results back to the main page window and have it manually post-back the results to the server. This is a little more involved but it is possible.

Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate

I'm currently working on a dynamic core for several webprojects. It has a core that uses a treeview and a menu. And then for each specific projekt it loads several different wuc into a maincontent. Some business projects use business related wucs while others uses different ones. So the span of wuc's is really big.
Now to my problem, whenever a user press a menuitem or a treeitem it loads a wuc to the maincontent linked to that object.
But I'm having some viewstate errors and i've been looking around for 2 days now and none of the solutions explained are working for my projekt.
All my wuc has to have viewstate enabled.
Cycle is ->
Page(Control A) does postback with variable to change control to ControlB in wucPanel(UpdatePanel).
OnLoad LoadRequested Wuc.
Current code is
protected void Load_Page(object sender, EventArgs e)
{
//Code to decide which wuc to load.
UserControl wucc = (UserControl)Page.LoadControl(sFilePath);
ParentControl.ContentTemplateContainer.Controls.Add(wucc);
}
I've tried several fixes like adding diffrent ids to the wuc, but this either disabels the internal functions of control like handlers etc or generates the same viewstate error.
One solution i found was to load ControlA and then just removing it and then load ControlB. But this disabled the scripts for my 3rd party controller (Telerik).
I've also read about having diffrent PlaceHolders for each typof but since i expect havign up to 50 diffrent Controls I don't feel this is gonna help me.
And moving from Page_Load -> Page_Init generated the same error.
Error:
Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request. For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request.
In your case Anders, you still need to add the old control to your page in the init method along with the new control that you now want to add. Keep a reference to this old control that you have just added in a class level variable. So something like
Control _oldControl = null;
protected void Init_Page(object sender, EventArgs e)
{
//Code to decide which wuc to load.
UserControl wucc = (UserControl)Page.LoadControl(sFilePath);
ParentControl.ContentTemplateContainer.Controls.Add(wucc);
_oldControl = wucc as Control;
//Now add the new control here.
}
//override the LoadViewState method and remove the control from the control's collection once you page's viewstate has been loaded
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
ParentControl.ContentTemplateContainer.Controls.Remove(_oldControl);
}
Hope this helps. If it did, please check the checkbox next to this answer to accept it and vote it up if you like :)
In order to avoid ViewState related errors please make absolutely sure that in Page_Init you create the same control tree that was created the previous time ViewState was saved i.e. the previous postback. Simple page life cycle:
Page Init - create the control tree
- View State is loaded and applied here
Page Load - already loaded view state, you can do modifications to the control tree here
- Save View State
Page PreRender
For what it’s worth I recently had the same problem.
My scenario was as follows.
A fixed panel of filters (dropdown lists and textboxes) which built a search SQL string. On submission of the search consequent results were displayed in an editable gridview beneath.
On editing the gridview I cold effectively change the state of a database record thus removing it from the gridview under the filters previously chosen. In some cases this resulted in no results being returned thus causing me to hide the gridview.
I then found that if I used the new state of the record in the filter and resubmitted the search that error sometimes occurred.
The problem I eventually found had nothing to do with enabled viewstates etc but simply that the empty gridview, though no longer visible (changed programmatically), had not been rebound to a null datasource.
This appeared to cause the conflict and the error.
So it appears as though in my case the viewstate issue arose from a non-visible gridview that contained non-refreshed data.

Loading one user control after another has loaded - ASP.NET WebForms

I have a UserControl A that has to be loaded first and after that completes loading, I need to load a UserControl B.
I prefer to add both these user controls on the page at compile time (would like to avoid dynamic loading if possible).
If I add user controls on the page at compile time and set visible to false for User Control B, does it still execute the B's code behind? I can then set the visibility to true after loading User Control A
Should I be using events/delegates for notifying the completion of loading User Control A?
Don't load everything in the page event in control b, just put a method on control b to be called. Then add an event to control a which the page consumes, when the event is raised, call the load method on control b.
Edit: SampleCode
Ok so for example, create
a ASPX page
2x user controls
Put both user controls into the aspx page.
<cc:control1 runat="server" id="control_one" />
<cc:control2 runat="server" id="control_two" />
Then in control 1, create a delegate and event.
public delegate void MyCustomEvent (EventArgs args);
public event MyCustomEvent MyEvent;
protected void Page_Load(object sender, EventArgs e)
{
MyEvent(e);
}
So I have the event raised on page load. So you would have your logic in there thats required, when your done, calls MyEvent event.
In the page you want to add a handler for that event so when it's called you can do something with it.
protected override void OnInit(EventArgs e)
{
control_one.MyEvent += new WebUserControl1.MyCustomEvent(control_one_MyEvent);
base.OnInit(e);
}
void control_one_MyEvent(EventArgs args)
{
control_two.MyCustomLoad();
}
So when the page is initialized I add the event handler. In the event handler I call a custom method on the second control to load stuff.
Then in the second control I have:
public void MyCustomLoad()
{
//Stuff only loaded when event is raised and calls this method.
}
So this allows control 1 to load something, say it's done, when the page knows it's done, it can tell control 2 to do something.
Edit: After discussing this with a friend I'll explain what I mean by controlling the order.
You cannot control the order of page-life-cycle events. i.e: You can't have Control A, run through all it's page-life-cycle events, then once it's done, have Control B run through all it's page-life-cycle events.
If you do-away with the page life cycle, you can do a degree, as my example above shows, create a way of controlling the order in which the controls are rendered. By raising an event(s) at certain points when Control A is finished, you can tell Control B to do something.
The intermediate between the two controls is the page which handles the events raised by Control A which calls a method on Control B. You (well you can hack around to do it) can't specifically make Control A tell Control B to do something because that creates a direct dependency between the two controls which is bad.
Yes, the code behind will still run
Events could be useful
But if your controls have a specific dependency on each other, maybe they should just be a single control?
This is a fatally-flawed design. You should design your UI so that it doesn't matter in what order the controls load. The order in which controls load is outside of your control.
To address "Phill's" issue with an Order/Orderlines control pair:
I assume that the Order control was developed because it's useful by itself. I assume that OrderLines was developed to be able to show the line items for a given order displayed by the Order control.
I contend that there should be a single, composite control which combines Order and OrderLines. this control will pass to the OrderLines control, a DataSource consisting of the line items it is to display. This makes OrderLines independent of any other control - it simply displays the data it is told to display. It has no idea where that data came from.
Note that this can extend to a typical grid / detail / detail lines scenario, where you pass the grid a set of orders; when selected, a particular grid row will pass the Order control the selected order; when its' time to display the line items, pass the line items collection of the current order to the OrderLines control, etc.
This leaves each control with nothing to do but the Single job it is Responsible for.
"I have a UserControl A that has to be loaded first and after that completes loading, I need to load a UserControl B.
I prefer to add both these user controls on the page at compile time (would like to avoid dynamic loading if possible). "
I would suggest using WebFormsMVP: -
http://webformsmvp.com/
http://wiki.webformsmvp.com/index.php?title=Main_Page
As well as being a good implementation of Model-View-Presenter, one of the most useful features of this framework is its support for Messaging.
In a nutshell, you create Message Types, and your usercontrols (views) can post messages of whichever type you need to a message bus. Other controls can subscribe to messages of a particular type and the WebFormsMVP framework will ensure they are delivered.
This allows you to handle interaction between usercontrols by messaging publish & subscribe, without worrying about which order they load in.
Your only other option is to use dynamic control loading because, as others have pointed out, you can't rely on the order in which ASP.NET loads controls into a container.

ASP.net ViewState - Even when disabled, some viewstate exist. Why?

Even when on the page, the EnableViewState property is disabled, I am still seeing some viewstate existing on the page:
"<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="VkBAB3n5LZYtY+nTzk1vEu1P/6QLf4qzFIKzpFRJe3DMf8UseUA/1RsO409HJX4QhkROSP0umoJvatjK/q+jXA==" />"
My question is why?
It's the control state.
If you really want to get rid of viewstate and controlstate you can use this code in the code-behind for the page, or in any class that the code-behind derives from
class MyPage : Page {
private class DummyPageStatePersister : PageStatePersister {
public DummyPageStatePersister(Page p) : base(p) {}
public override void Load() {}
public override void Save() {}
}
private DummyPageStatePersister _PageStatePersister;
protected override PageStatePersister PageStatePersister {
get {
if (_PageStatePersister == null)
_PageStatePersister = new DummyPageStatePersister(this);
return _PageStatePersister;
}
}
// other stuff comes here
}
Be very careful when doing this, though, since you're violating the contract with the controls. MSDN explicitly states that control state is always available. In practice, however, it has worked for me.
Edit:
Since I was downvoted, I like to point out again: Don't do this unless you know exactly what you are doing. In my case, almost the entire application was written in client-side javascript, and on those few occations where postbacks occurred, I always used the Request.Form collection to retrieve the values. Do not use server-side controls for anything but simple rendering if you do this.
This could be controls that are using ControlState. Any control that has control state will ignore your ViewState settings.
This article is a little old but to my understanding most of the points are still valid:
You must have a server-side form tag () in your ASPX page if you want to use ViewState. A form field is required so the hidden field that contains the ViewState information can post back to the server. And, it must be a server-side form so the ASP.NET page framework can add the hidden field when the page is executed on the server.
The page itself saves 20 or so bytes of information into ViewState, which it uses to distribute PostBack data and ViewState values to the correct controls upon postback. So, even if ViewState is disabled for the page or application, you may see a few remaining bytes in ViewState.
In cases where the page does not post back, you can eliminate ViewState from a page by omitting the server side tag.
http://msdn.microsoft.com/en-us/library/ms972427.aspx
This is an absolutely fantastic article on ViewState if you develop in ASP.NET read it!
ASP.NET ViewState Helper is also a nice tool for seeing what's going on in your ViewState
Controlstate can be the causes. Control state can not be disabled. In ASP.NET 2.0 there is a distinction between data necessary to make a control work (controlstate), and other data (viewstate)
And yes some of the controls don't work without controlstate.
If you want to know which one is causing it or what the viewstate contains check out a viewstate viewer
The Controls which implements IPostBackEventHandler 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 will not get any state information from posted back data and hence depend entirely on viewstate to maintain the state.

Resources