Search code examples
c#asp.netwebformsviewstate

How are ViewStates accessible everywhere without being declared?


I was always under the impression that to access a variable in multiple methods, you'd either have to declare it as a class member or pass it in as an argument. However, I was looking over some sample code recently to learn .NET, and I came across something called a ViewState. I understand it's meant to track some Pages and Control Properties, but I don't understand how it's being used here.

The code looks somewhat like this:

private void RowValidating(object sender, EventArg e) {
      ViewState[Backup] = ViewState["TestId"];
      // more code that does not include ViewStates
}


private void UpdateBox() {
     // some code that does not include ViewStates
     int box_id = ViewState[Backup];
     // ...
}

How is ViewState accessible everywhere? It is not declared anywhere in the class or in any of the other class files, and this [Backup] key is just sort of created without initializing it. As far as I can tell, ViewState[Backup] does not exist until RowValidating is called.

Would it be possible to set ViewState as a global variable? Or could I always just make my own key that is accessible anywhere? It seems to behave like a dictionary, but I thought the notation was dict.Add(item, value), not dict[item] = value when working with a new item. It must be initialized somewhere, perhaps in some imported library?


Solution

  • Both Session() and ViewState are and can be used to persist values in your code. You don't have to declare them, they are built in features of asp.net

    Session() is per user and thus is often used to persist values or even pass values between pages. However in some cases ViewState is preferable.

    So for example if you have a productID or maybe even a house you are about to buy? Well, if you have two tabs open or even two different browsers open then Session() applies to all instances of the browser(s) in question open. So if a user has two seperate browsers opened, then the "ID" value you persist in session() will apply to both (so, be carefull, which house ID are you about to buy when you have 3 browser pages open to 3 differnt houses open? So session() is global to the user.

    So for say "persisting" a row of data to pass to the next web page/form, Session() can be great - but keep in mind it is shared among all pages opened and in operation by that user. So session() is still per user - but global to that user.

    Session() can be server "in memory" (the default). However, if you are using a server farm, then each of those multiple servers can't share their memory, and as such you have to adopt what is called SQL server based session. So in place of holding these values in memory, the session() state is shuffled from a serialized "blob" stored in SQL server. So if you hosting your site say on a cloud based system like Azure (as opposed to regular hosting), then session() can't persist on these so called "large services" based systems (or you are using a server farm with load balancing in which you have multiple-servers hosting the site for scalability reasons). Since multiple copies of the hosted web site can exist at the same time, then a means to have a common session() is required (so they shove a blob thing into SQL server). So you can still use session(), but it actually stored in sql server. It is noted that in some cases session() based on SQL server can cost performance. As high as 10% - perhaps a bit more. I find that in most cases you not notice this performance hit. But it works seamless() and in fact adopting SQL server based session will mean that session() is not frequent lost due to site execution errors. I had all kinds of issues with a site losing session(). If the web hosting and management system puts the server to sleep, or even .net code errors occur, it can (and will!!) often cause a application pool re-start - and that blows out session() (but not with SQL server based ones - they are rock solid).

    ViewState is often preferred since it is by EACH NEW web page. And this is stored 100% in the browser. So to persist that houseID or product you about to purchase, then this occurs by page, and not all web pages in use by the user (so in this case, VieweState would be a far better choice). ViewState is thus stored by the browser and is much the SAME mechanisum used when you enter bunch of values in text boxes, and then do a post back. The web page travels up to server - page is processed and sent back down. But you will notice that MOST controls on the page retain their value. To achieve this then ViewState is used. And this applies to hidden text boxes (or hidden fields - much the same as a hidden text box). So this encrypted blob lives in the browser client side. And this blob thing thus goes along for the post-backs and round trips to keep those controls values in-tact.

    So you can use session(), or ViewState But, as noted, you don't want to stuff too much into that ViewState, since it becomes part of that round trip life cycle. But ViewState as noted is often preferred since it is per page operation. However, since each new browser page opened creates a new local per page ViewState? Then ViewState can't as a general rule be used to pass values between web pages like Session() can.

    However, you CAN pass all values of all controls to the next page. You can do this by using the post-back URL of a button. When you do this, then on FIRST page load, you can use the page.previous property in the on-load event. This will give you use of ALL values from the previous page - and you don't need Session() to do this. You can also use page.Previous if you do a server.TransferRequest as opposed to a Response.Redirect().

    Last but not least? You see a lot of sites have a whole bunch of parameters in the URL. So this is often used and has a long history of use. Of course users can mess and change with these values - but they are still often used and often make the URL's rather ugly. For this reason I do like asp.net sites, since then URL's don't expose a bunch of stuff in the URL as parameters and keeps such information out of site and mind. You see a lot of shopping site still using parameters and values in the URL - and they do this for reasons of scalability - (they don't have to store the persisting values server side - it saves resources).