When it comes to working with ASP.NET most developers who have done standard desktop development always run into the problem of their class variables not retaining their values. You create a variable at the class/page level and expect that when you click a button or change a server control on the page that those variables will be there when its event is triggered. But in many cases they are not and it can be frustrating because you can see them right there in the code, initialized to some value, and yet the code said they are not set. I guess the even more frustrating part is that when you go on the forums and ask the question, all people do is point you to the same MSDN article talking about the page life-cycle and tell you that the web is stateless. But what exactly does that mean? We will get to the root of the cause and hopefully answer the question once and for all.
When you surf to a page of a website, your browser makes a request to the server asking for a specific page of HTML to be returned. In the case of an ASP.NET site, that request is passed to the .NET framework, processed, transformed to HTML and then returned. The important thing to know here is that once it returns the HTML, it forgets about the request you just made. It is like dealing with someone with short term memory of less than a minute. Here is the reason your variables don’t hold their values. It forgets them each time a request is finished. This is what is meant by the web being stateless. Unless you store the value somewhere more permanent (like a database, session variable, cookie or viewstate) it forgets all about the things you calculated on that one request.
When you request a page the first time, you set your variables to some value. Perhaps you fetched that value from a database or did some calculations and set them to the result of that calculation. Let’s say you set these class variables in a button click event. The page returns to the user. The user then clicks another button. This second click is a completely new and different request. It starts out with fresh class variables (yeah the ones you thought would have remained set) and calls the Page_Load event to load the page.
In order to fix the problem, we have to understand a bit about the page life-cycle. However, before I just kick you over to the MSDN article and leave you to fend for yourself on that rather dry page, I will just cover some of the events you might need to play with to remedy the situation. Each time you request a page, and the ASP.NET tech does its work, it calls some standard events in a particular order. It calls some initialization events, loading events, controls events (like button click events), rendering events and finishing events. If we understand that these events always fire and in a specific order we can understand that if we setup our variables in these events, they will be available to other events later down the chain.
One of these events is the Page_Load event. It is always fired when the page is being, well, loaded. Makes sense doesn’t it? It is a great event for establishing database connections and… initializing our class variables! We can rely on this event to setup our variables because even when we click a button, the Page_Load event fires first before the button click event. We set the variables in page load, then use them in the click event. When we post back the page again, the page load event is again ran and then the other event is triggered. Think of the Page_Load event as the “Prepare the page” event so that when another event is triggered everything will be setup.
To save your values between requests you are going to have to dump the values somewhere that the Page_Load can read them again on the next page load. Where you put these values is really up to your application but if you save them to a database, you could read them again from the database on Page_Load. Another place you could save them is in a Session Variable. Then on Page_Load you read them back out of the session (or read them from session in the click event itself. It is really up to you). It is the same with cookies or viewstate. Each of these methods has their advantages and disadvantages. Some last longer than others and some are easier to work with. In the end ask yourself “Do I really need to persist this data to begin with or can I just easily recalculate it again on next page load?” If you are just adding 2+2, why save the 4 when you could just do 2+2 again? If the calculation takes a bit of time, then it might be perfect to store the result and retrieve the result again instead of doing the whole calculation from scratch each time.
Seeing the pattern above you can see why many developers like to setup an “initialize” or “config” method that is called from Page_Load to put things on the page back to some known state.
ASP.NET variables forgetting their values seems like a real pain sometimes. But you know, this isn’t really a problem with the framework. It is just how the web works. Web servers see thousands or millions of requests a day and if it had to remember everything about each one of them on every request, you could see where the problem might happen. It would have to remember that one off time someone came to the site and clicked a button as well as that person who visits every day.
By utilizing events like Page_Load to set your class level variables you should have no problem working with them later on in the life-cycle. This is because the Page_Load event is often triggered before any control events. Read values from storage, set your variables and you are off to the races!
To keep values around from page request to page request you are going to need save them in some sort of persistent storage. Some options might be sessions, cookies, viewstate, databases or even files. But if you understand that on each request a certain number of events are triggered, and in a specific order, you can plan when to initialize (Page_Load), read (control events like button clicks) and save your data (also in control events) without a problem.
Thanks for reading! 🙂