Maintaining dynamic control state between postbacks - asp.net

I have a dynamic ASP.NET form which I recreate evertime I postback. My values persist no problem.
I am however having a challenge maintaining attributes on Postback. For example, I have user defined code which may enable or disable a field when someone is first presented with the form. If a user posts the form I need an easy way to make sure the field stays enabled or disabled.
Does this make sense? Is there an easy way to do this?

ViewState is the preferred method of persisting information between postbacks that doesn't need to live beyond the scope of a single page. You can store information pretty easily there.
An easy way to accomplish this is to use a property in the control, or the page that abstracts the use of ViewState from you.
protected Boolean IsFieldVisible
{
get{ return (Boolean)ViewState["SomeUniqueKey"] ?? false; }
set{ ViewState["SomeUniqueKey"] = value; }
}
This will maintain the value between postbacks.

Related

How can same user control render different output?

Ok. Here we go. I am not sure if anyone here has implemented this, but I have a user control in my Webforms application which I am calling on several forms.
This user control has a dropdown which calls the stored procedure and filters the dropdown according to a certain date. However, on one of the forms, I want same user control to still call the stored procedure but not filter at all, just fetch all records.
Basically, I want same user control to do one thing on one form and another thing on another form. I want to use same user control since there is only small change. Rest is the same and hence I want to avoid creating another form.
Is this possible?
Thank you.
The easiest way is create a property on the user control:
public bool SOmeCOnfigurableSetting
{
get { return ((bool?)ViewState[".."]).GetValueOrDefault(false); }
set { ViewState[".."] = value; }
}
It can be any type, not just bool. In each page, set the property on the user control definition, and this controls the filtering or other functionality.

Huge ASP.NET Web Forms

I looking for strategies others have taken for handling ASP.NET web forms with huge numbers of fields. For example, we have a single page that can have around 200 fields and 3 data entry grids in user controls, Now were looking to add even more. It seems to me that at some point the viewstate, or something, is going to break down. So I'm interested to hear how others have handled this level of fields.
MORE INFO BASED ON GOOD FEEDBACK BELOW: I'm thinking maybe changing my main form to more of a dashboard, and when the user wants to enter/edit a data section they get redirected to a new page entirely. When they're done it redirects back. We already have user controls for the 3 grids (totally different types of data). But User Controls I'm finding are nightmares as far as when they render, interactions with the "parent" etc.
I have a form with over 1500 form fields, no issues as of yet. You should be fine unless your server is resource anemic or you have extraordinary loads.
You should however take note of this massive gotcha that took me unawares:
http://support.microsoft.com/kb/2661403
By default, 1000 form controls is the max you can submit to your page. And there is no error thrown, the page will only accept the first 1000 items, and ignore the rest. Pretty awesome discovery in a production environment...
Fortunately you can override that default with this in your web.config:
<appSettings>
<add key="aspnet:MaxHttpCollectionKeys" value="10000" />
</appSettings>
I wouldn't recommend forms with that many controls, but it was at the insistence of the client :)
I looking for strategies others have taken for handling ASP.NET web
forms with huge numbers of fields.
I like to share "a trick" that I use on the rare case of a form with hundreds of fields. On post back I eliminate the fields that actually not change, or they have some default input. On post back I know the fields that I have eliminate and usually for the default action I do not need to do anything. Eg a not select check box, or an input field that have not change, etc....
That way, the actually post is significant smaller. For example on jQuery here is a simple code:
function cOnSubmit()
{
jQuery(".MyInputCss").each(function(index, domElem)
{
var me = jQuery(domElem);
// just an example - if the default have selected of no action, I eliminate it.
if(me.find("input[type='radio']:checked").val() == "-1")
{
// removing the name is not take part on the post back
me.find("input").removeAttr("name");
}
});
return true;
}
and on the form I call this function as:
<form .... onsubmit="return cOnSubmit();">
It seems to me that at some point the viewstate, or something, is
going to break down.
1) If you have a lot of control, you will end up with Operation is not valid due to the current state of the object.
It can easily be fixed by using MaxHttpCollectionKeys like Chris Hardie's suggested.
Note: a label server control is also counted as one control in addition to textbox server control.
2) The another problem I can think of will be large ViewState.
In order to solve this, you can either store ViewState in StateServer or SQL Server.
Update 12/20/2013:
Sorry, I forget to mention how to save ViewState to Session.
Since you already store SessionState is SQL Server, all you need is to inherit the aspx pages from this BasePage.
public class BasePage : Page
{
protected PageStatePersister _persister;
protected override PageStatePersister PageStatePersister
{
get { return _persister ?? (_persister=new SessionPageStatePersister(this));}
}
}

Losing state of WebForm User Control

First of all, I have no experiences with ASP.NET WebForms. However, I inherited a very old WebForm application where I have to do maintenance from time to time. This is such a situation:
There is a user control that has private instance variables. The problem is, that the values of these instance variables get lost, most likely after page reload. What I found out so far is, that it seems that the control class gets recreated frequently. What would be helpful, would be answers to the following questions:
Do WebForm User Controls do maintain a state?
If yes, how is it done in general (pointers to online resources for details appreciated)
If no, can it be implemented somehow? Any samples?
Probably the most common way to maintain state is to use ViewState rather than private instance fields. For example, if your UserControl contains a property Text, you can define it as follows:
public string Text
{
get { return (string) ViewState["Text"]; }
set { ViewState["Text"] = value; }
}
You can also delegate a property to a child control. In this case the child control will maintain ViewState for you (provided EnableViewState is true). For example:
public string Text
{
get { return MyTextBox.Text; }
set { MyTextBox.Text = value; }
}
Google for ViewState for more info. There are pitfalls and it's a good idea to understand it thoroughly.

asp.net code behind variable

I am generating some head html in page load and because of that I query database once. in the page I query database again and put data into html with inline code.
my question is is there better way to do this? I dont want to query database everytime and reach out those filled variables from inline code. something like page.addVariable in page_load and reach those at inline like page.variables["variablename"]
thanks in advance
If I understand what you are asking, you can make an accessor and set it to Protected. That will allow you to access it from the page.
If you want to prevent calling the database on callbacks, you could always add the information to the view state on the page.
Information on the view state, hidden fields, and cookies:
http://www.csharphelp.com/archives/archive207.html
I'm not sure if this is what you're after, but you can use a HiddenField to store any data you want on the page.
Also, if you don't need it to be on the page, you can use Session or ViewState.
Here's an example of using ViewState as a property (NB. you can interchange ViewState with Session, look at the links I gave you for an explanation between the two):
public string YourProperty
{
get
{
object content = ViewState["YourProperty"];
if (content == null)
{
return string.Empty;
}
return content.ToString();
}
set
{
ViewState["YourProperty"] = value;
}
}
Note, that anything you put into ViewState or SessionState must be marked as Serializable.
If it's quite a simple class, just mark the class with the [Serializable] tag.
Is the data you retrieve from the database page specific, user specific or global to the entire application?
If the data is user specific you can use Session State.
If the data is global to the entire application you could use Application State.
Whichever you use, you can implement the data retrieval in the Session_Start (will be called only once for each user) or Application_Start (will be called only once when the web app starts) events in a Global.asax file.

ASP.net drop down dynamically styling and then remembering the styles on aborted submit

So, I've got an ASP drop down list (this is .net 2.0). I'm binding it with data. Basically, when the page loads and it's not a post back we'll fetch record data, bind all the drop downs, and set them to their appropriate values (strictly speaking we: initialize page with basic set of data from DB, bind drop downs from DB, fetch actual record data from DB, set drown downs to appropriate settings at this time). What I want to do is selectively style the list options. So the database returns 3 items: ID, Text, and a flag indicating whether I the record is "active" (and I'll style appropriately). It's easy enough to do and I've done it.
My problem is what happens when a form submission is halted. We have slightly extended the Page class and created an AddError() method, which will create a list of errors from failed business rule checks and then display them in a ValidationSummary. It works something like this, in the submit button's click event:
CheckBizRules();
if(Page.IsValid)
{
SaveData();
}
If any business rule check fails, the Page will not be valid. The problem is, when the page re-renders (viewsate is enabled, but no data is rebound) my beautiful conditional styling is now sadly gone, off to live in the land of the missing socks. I need to preserve it.
I was hoping to avoid another DB call here (e.g. getting the list data back from the DB again if the page isn't valid, just for purposes of re-styling the list). But it's not the end of the world if that's my course of action. I was hoping someone might have an alternative suggestion.
I couldn't think of how to phrase this question better, if anyone has any suggestions or needs clarification don't hesitate to get it, by force if need be. ;)
I'm not sure I completelly understand what kind of styling you apply to your drop-down items, but it seems this style is something that the control does not preserve accross postbacks. Usually this kind of info will therefore need to be saved in the ViewState.
I see two options (other than re-loading from DB):
First method: Create your own drop-down control that inherits from DropDownList. Then save styling data in the control's ViewState bag when styling the items:
public void SetItemActive(ListItem item)
{
ViewState[item.Value] = "active";
}
then override the OnRender
protected override void Render(HtmlTextWriter writer)
{
....
foreach(ListItem item in Items)
{
if ( ViewState[item.Value] == "active")
{
** RenderActiveItem **
}
else
{
** RenderNormalItem **
}
}
Second method: is to save the active ID's in the Page's ViewState then re-style the dropdown on each postback using the data from the ViewState rather than from the DB
Well, I couldn't come up with anything except to go to the database to re-retrieve my list data when the Page was not valid, and re-style the control.

Resources