Viewstate is a new way of State Preservation proposed in. Net (in fact, it is also a new old bottled wine); we know that the traditional Web Program You can save the status in the following ways:
1. Application: This is the global storage area of the Web application in its life cycle. The data stored in the application is globally valid. net, there is an application pool, which stores several (or dozens) application instances, each request will take an instance from the pool to process the request, before the request is completed, this instance will not accept other requests. This leads to a problem where multiple applications, namely multiple threads, may exist at the same time, these threads all have the possibility of accessing the application. Therefore, thread synchronization needs to be considered when processing objects in the application. In fact, the application object implements a thread lock, the lock and unlock operations are automatically called when you call its own add, remove, and other methods. However, for performance considerations, the application does not automatically process thread synchronization for obtaining and operating the objects directly through the indexer or other methods. Code To handle:
Application. Lock ();
(INT) application ["count"]) ++;
Application. Unlock ();
It is worth noting that after the lock is called, if unlock is not displayed, the application object will be automatically unlocked at the end of the request, which prevents deadlock, however, to ensure code robustness, the unlock method should be called immediately after the lock is called and the modification is completed.
The application object is essentially a hash table, which stores objects according to the key value. Because the objects are global and stored on the server, and multiple threads are simultaneously accessed, the application stores data that is frequently accessed, rarely modified, and used by at least a majority of global functions, such as counters or database connection strings.
2. Session in ASP. net internal, there is a stateapplication to manage the session, in fact, is a helper process, processing session expiration, create special requests, when receiving each request, the auxiliary process will call the status server (you can use the web. config sets different status servers) to obtain the session. If there is no session for which the sessionid should be set, a new session will be created and bound to the context (httpcontext). Unlike ASP, there are multiple session Status servers, currently in ASP. net has three internal implementations:
1) inprocstateclientmanager: this is a traditional session storage method, but there are still some nuances.
2) sqlstateclientmanager: saves the session to the database.
3) outofprocstateclientmanager: saves the session outside the process.
The session mechanism of ASP. Net has a feature that the auxiliary process for processing the session is separated from the State server for storing the session. According to msdn, the following benefits are provided:
"Because the memory used for session status is not in the ASP. NET auxiliary process, you can recover from application faults ."
"Because all statuses are not stored together with the secondary process, you can partition the application across multiple processes cleanly. This partition can significantly improve the availability and scalability of applications on computers with multiple processes ."
"Because all statuses are not stored together with the secondary processes, You can partition applications across multiple secondary processes running on multiple computers ."
ASP. in my opinion, the session mechanism of net is flexible, and the internal implementation is also clever. But in fact, because there is not much test done, will the application be as beautiful as it said, do not dare to pack tickets. I will write an article separately. Article ASP. NET session mechanism.
3. There is nothing to say about Cookie. In fact, there is no difference between ASP. NET and ASP cookies. This technology may be mixed and relies on client implementation, and MS has no improvement.
4. viewstate: This is what we will focus on today. In fact, viewstate is not mysterious. It is a hidden field, but it is the basis for saving the status of server controls; unfamiliar friends can use IE to view the HTML source code and find a hidden field named "_ viewstate". There are a lot of messy characters, which are the viewstate of the page.
People who have done web programs may have this kind of painful experience. Sometimes, in order to process complex functions on the page, many hidden operations are often added, then, the server uses a lot of judgments to analyze the current status, which is annoying. It is even more difficult to write the code. In fact, viewstate helps our system implement the function of saving the control status, the server control can be saved among multiple requests.
Well, the introduction is here. Today we are not discussing the use of viewstate, but exploring the essence of this thing from the inside.
First, create a test page:
<% @ Page Language = "C #" codebehind = "viewstatetest. aspx. cs" autoeventwireup = "false" inherits = "csdntest. viewstatetest" %>
<! Doctype HTML public "-// W3C // dtd html 4.0 transitional // en">
<HTML>
<Head>
<Title> viewstatetest </title>
<Meta name = "generator" content = "Microsoft Visual Studio 7.0">
<Meta name = "code_language" content = "C #">
<Meta name = "vs_defaultclientscript" content = "JavaScript">
<Meta name = "vs_targetschema" content = "http://schemas.microsoft.com/intellisense/ie5">
</Head>
<Body>
<Form ID = "viewstatetest" method = "Post" runat = "server">
<Asp: button id = "btnpostback" runat = "server" text = "post back" width = "85px"> </ASP: button>
<Br/>
<Asp: checkbox id = "chktest" runat = "server" text = "This is a check box"> </ASP: checkbox>
</Form>
</Body>
</Html>
This is a simple page designed with vs. net. It contains a server-side button and a checkbox, And then we respond to the button event on the server side:
Private void btnpostback_click (Object sender, system. eventargs E)
{
[1] response. Write ("viewstate:" + request. Params ["_ viewstate"] + "<br/> ");
[2] string decodevalue = encoding. utf8.getstring (convert. frombase64string (request. Params ["_ viewstate"]);
[3] response. Write ("viewstate Decode:" + decodevalue + "<br/> ");
[4] object viewstate = (New losformatter (). deserialize (request. Params ["_ viewstate"]);
[5] response. Write ("viewstate object:" + viewstate. GetType (). Name );
}
For convenience, I added a row number. In the first line, we typed out the value of viewstate. What is the second line? In fact, a string stored in viewstate on the client is the internal viewstate serialized in some way and then encoded in base64. Therefore, we can re-encode the base64 encoded string; as for the fourth line, I will not talk about it first. Let's look at the execution result first:
After running, there is nothing on the page, except the button and checkbox (nonsense :), we click the button and the result is as follows:
[A] viewstate: ddwxmju2mdi5mta3oztspgnoa1rlc3q7pj6gg0qzm + 7gacywcy0hnrct9tooda =
[B] viewstate Decode: T <1256029107; L> d3i S -! T
[C] viewstate object: triplet
Then let's analyze this result. The value displayed in a is the value uploaded from viewstate to the client. The value displayed in B is the value after base64 anti-encoding. It seems that nothing can be seen from this, in C, A: triplet? What is this? Let's go back to the above Code:
Object viewstate = (New losformatter (). deserialize (request. Params ["_ viewstate"]);
note that we use a losformatter class. In fact, this class is ASP. NET provides a serialization class for viewstate. It has two methods: serialize, which is to serialize an object, deserialize, and deserialization, here we use the deserialization method to directly deserialize viewstate into an object, and then type this object. This object is the triplet type, in fact ASP. the viewstate stored on the page in. NET is of this type. Let's analyze the losformater and then explain it in detail.
let's look back at the result B: T <1256029107; L> d3i S -!
T. In fact, by viewing the losformatter decompiled code, we can see that the serialization method is very simple, that is, to judge the type of the object to be serialized. If it is not a direct serialization type, record its type and recursively serialize its attributes. We can see that "T" in B Indicates the triplet type, which has three attributes, these three attributes are included between "<" and ">", separated by ";", and the final d3i S -!
T according to my analysis, it should be a hash value that prevents viewstate changes. This is not very definite, because the decompiled code is really ugly, I did not read it carefully after learning it.
we just analyzed that the viewstate deserialization in the page is the triplet type. In fact, this class is found in msdn. It is an object that contains three objects, to put it simply, it is a big box that can put three boxes (it seems to be confused, haha). It has three attributes: first, second, thrid :), three objects are represented respectively.
in the corresponding page, first is page. the return value of gettypehashcode (). This method is system. web. UI. A protected virtual method defined by PAGE, returns an integer, implemented by the class generated by the aspx file, because this class has ASP. net is responsible for generating and compiling the Source Code at runtime. It calculates a large constant as the return value, the returned value is unique among all pages of the web application. (Put forward an external question, Asp. net automatically generated source code can go to the System Disk: \ windows \ Microsoft. net \ framework \ v1.0.3705 \ temporary ASP. net files). The unique hash value is used to generate a tag in viewstate, so that this viewstate applies only to the corresponding page.
Second is the object returned by viewstate of the page Control tree recursively saved through the control. saveviewstaterecursive method, that is, the real viewstate data.
third stores a list of control names on the current page that require PostBack.
After analyzing the composition of the viewstate of the page, let's look at the implementation of the viewstate of control. Viewstate is system. web. UI. A Property Implemented by the control class. The type of this property is system. web. UI. statebag: This class includes the implementation of viewstate data structure. In fact, it is an internal hash table that stores and retrieves data through key values.
How does the Server Control Save the status?
We know that all server controls are derived from system. Web. UI. Control, so they all have the viewstate attribute. Within control, two protected virtual methods are defined:
Protected virtual object saveviewstate ()
And
Protected virtual void loadviewstate (Object savedstate)
These two methods are used to derive the child control to save and read its own viewstate. For example, we have a self-written control that saves a string to viewstate, then our method is roughly like this:
Protected virtual object saveviewstate ()
{
Object [] States = new object [2];
States [0] = base. saveviewstate (); // remember to save the viewstate of the parent Control
States [1] = "Hello, I'm tietong! "; // Save your own
Return states; // return the repackaged object
}
When obtaining:
Protected override void loadviewstate (Object savedstate) // The savedstate here is the object array returned when we save
{
Object [] States = (object []) savedstate;
Base. loadviewstate (States [0]); // parse the data of the parent class for himself.
String mydata = (string) States [1]; // obtain our own data
}
We can save it in our own way. We don't have to use arrays like above. In fact, we can use any object that supports serialization. The parent class doesn't care about how to save subclass, we only need to use the same method when saving and load, and pass the correct data to the parent class method.
Another problem is that the viewstate of the control we use is a key-Value Pair such as key-value. How does it save it?
In fact, it is very simple. There is a class named pair under system. UI. Web. It is similar to Triplet, but it only contains two objects. When statebag is saved, first stores the array of all key values, and second stores the array of all values.
Now, we have learned how viewstate is serialized and saved to the client, and how controls save their own viewstate. How are these two combined?
That is, how does the viewstate of the Control tree of the entire page be saved and read?
There are two internal methods in control:
Internal object saveviewstaterecursive ();
Internal void loadrecursive ();
These two methods are composed of system. web. UI. the savepageviewstate method is called by PAGE after the render ends. The savepageviewstate method calls the saveviewstaterecursive () method of control. This method uses recursion to call each control. the saveviewstaterecursive method of controls is used to save the viewstate of all controls in the control tree. At this point, a wise friend may ask, since saveviewstaterecursive is a recursive call to save the method, what is the use of the saveviewstate () method we wrote above?
We know that control. there may be many controls, and our saveviewstate () only saves the data of the current control, but does not record the structure of the Control tree, so if we recursive saveviewstate () if the method is used to save data, the structure of the Control tree will be lost, so the structure of the load cannot be restored. In fact, the code in the saveviewstaterecursive method is as follows:
[1] obtain the viewstate of the control (call the saveviewstate method)
[2] loop child Control
{
Define two dynamic arrays, one for storing the control index, and one for storing the values returned by recursively calling the saveviewstaterecursive method of the child control.
}
[3] define a triplet (haha, this thing appears again)
[4] first save the viewstate of this control
[5] Second: Save the sub-Control Index
[6] third: Save the return value of the saveviewstaterecursive method of the recursive subcontrol
[7] returns triplet
In this way, the viewstate of the entire control tree and the structure of the Control tree are saved.
The load method is similar to the Save method, but the load method retrieves the index of the sub-control from the savedstate to recursively recursive the loadrecursive () method of the sub-control, this ensures that the stored data is correctly transmitted to the Child control.
here, we have a general understanding of the implementation of viewstate, and finally come to some conclusions:
1. viewstate is stored on the client, which reduces the burden on the server, is a better way to save data.
2. Because of the limitations of viewstate, only serializable objects can be saved, and it is best not to put too many things, saving time, so as not to slow down the transmission speed, and increase the load on Server Resolution.
3. We can obtain the value in viewstate in a simple way. We have discussed some of the above, although the parsed code is not written, however, the losformatter can be used to obtain the object after viewstate deserialization, so it is easy to parse the object. Therefore, viewstate is still relatively poor in terms of security, we recommend that you do not
store confidential and sensitive information. Although viewstate can be encrypted, viewstate must be stored on the client, which poses a security risk.
4. From the technical point of view, viewstate has no new ideas, but it is clever to combine the server control design.