WEBSITE

ASP.NET State Management : The View State of a Page (part 4) - Keeping the View State on the Server

5/15/2013 1:52:00 AM

5. Keeping the View State on the Server

As discussed so far, there’s one major reason to keep the view state off the client browser. The more stuff you pack into the view state, the more time the page takes to download and upload because the view state is held in a hidden field. It is important to note that the client-side hidden field is not set in stone, but is simply the default storage medium where the view state information can be stored. Let’s see how to proceed to save the view state on the Web server in the sample file.

Important

Before we go any further in discussing the implementation of server-side view state, there’s one key aspect you should consider. You should guarantee that the correct view-state file will be served to each page instance the user retrieves via the browser’s history. This is not an issue as long as each page contains its own view state. But when the view state is stored elsewhere, unless you want to disable Back/Forward functionality, you should provide a mechanism that serves the “right” view state for the instance of a given page that the user is reclaiming. At a minimum, you need to make copies of the view state for about 6 to 8 instances. As you can see, what you save in the roundtrip is lost in server’s memory or server-side I/O operations. All in all, keeping the view state on the client and inside of the page is perhaps the option that works better in the largest number of scenarios. If the view state is a problem, you have only one way out: reducing its size.


The LosFormatter Class

To design an alternative storage scheme for the view state, we need to put our hands on the string that ASP.NET stores in the hidden field. The string will be saved in a server-side file and read from where the page is being processed. The class that ASP.NET 1.x actually uses to serialize and deserialize the view state is LosFormatter.

The LosFormatter class has a simple programming interface made of only two publicly callable methods—Serialize and Deserialize. The Serialize method writes the final Base64 representation of the view state to a Stream or TextWriter object:

public void Serialize(Stream stream, object viewState);
public void Serialize(TextWriter output, object viewState);

The Deserialize method builds an object from a stream, a TextReader object, or a plain Base64 string:

public object Deserialize(Stream stream);
public object Deserialize(TextReader input);
public object Deserialize(string input);

The LosFormatter class is the entry point in the view-state internal mechanism. By using it, you can be sure everything will happen exactly as in the default case and, more importantly, you’re shielded from any other details.

The ObjectStateFormatter Class

As mentioned, the LosFormatter class is replaced by ObjectStateFormatter starting with ASP.NET 2.0. LosFormatter is still available for compatibility reasons, however. The new serializer writes to a binary writer, whereas LosFormatter writes to a text writer. LosFormatter needs to turn everything to a string for storage, while ObjectStateFormatter capitalizes on the underlying binary model and writes out just bytes. As a result, ObjectStateFormatter serializes the same object graph into roughly half the size, and spends about half as much time in the serialization and deserialization process.

The Serialize method of ObjectStateFormatter writes the final Base64 representation of the view state to a Stream or a string object:

public string Serialize(Object graph);
public void Serialize(Stream stream, Object graph);

The Deserialize method of ObjectStateFormatter builds an object from a stream or a plain Base64 string:

public object Deserialize(Stream stream);
public object Deserialize(string input);

Creating a View-State-Less Page

The Page class provides a couple of protected virtual methods that the run time uses when it needs to deserialize or serialize the view state. The methods are named LoadPageStateFromPersistenceMedium and SavePageStateToPersistenceMedium:

protected virtual void SavePageStateToPersistenceMedium(object viewState);
protected virtual object LoadPageStateFromPersistenceMedium();

If you override both methods, you can load and save view-state information from and to anything. In particular, you can use a storage medium that is different from the hidden field used by the default implementation. Because the methods are defined as protected members, the only way to redefine them is by creating a new class and making it inherit from Page. The following code gives you an idea of the default behavior of LoadPageStateFromPersistenceMedium:

string m_viewState = Request.Form["__VIEWSTATE"];
ObjectStateFormatter m_formatter = new ObjectStateFormatter();
StateBag viewStateBag = m_formatter.Deserialize(m_viewState);

The structure of the page we’re going to create is as follows:

public class ServerViewStatePage : Page
{
    protected override
        object LoadPageStateFromPersistenceMedium()
    { ... }
    protected override
        void SavePageStateToPersistenceMedium(object viewState)
    { ... }
}

Saving the View State to a Web Server File

The tasks accomplished by the SavePageStateToPersistenceMedium method are easy to explain and understand. The method takes a string as an argument, opens the output stream, and calls into the LosFormatter serializer:

protected override
void SavePageStateToPersistenceMedium(object viewStateBag)
{
    string file = GetFileName();
    StreamWriter sw = new StreamWriter(file);
    ObjectStateFormatter m_formatter = new ObjectStateFormatter();
    m_formatter.Serialize(sw, viewStateBag);
    sw.Close();
    return;
}
private string GetFileName()
{
    // Return the desired filename.
    ...
}

How should we choose the name of the file to make sure that no conflicts arise? The view state is specific to a page request made within a particular session. So the session ID and the request URL are pieces of information that can be used to associate the request with the right file. Alternatively, you could give the view state file a randomly generated name and persist it in a custom hidden field within the page. Note that in this case you can’t rely on the __VIEWSTATE hidden field because when overriding the methods, you alter the internal procedure that would have created it.

The GetFileName function in the preceding code could easily provide the file a unique name according to the following pattern:

SessionID_URL.viewstate

Notice that for an ASP.NET application to create a local file, you must give the ASP.NET account special permissions on a file or folder. I suggest creating a new subfolder to contain all the view-state files. Deleting files for expired sessions can be a bit tricky, and a Windows service is probably the tool that works best. A Windows service, after all, can auto-start on reboot and because it runs autonomously from the ASP.NET application it can clean out files in any case.

Loading the View State from a Web Server File

In our implementation, the LoadPageStateFromPersistenceMedium method determines the name of the file to read from, extracts the Base64 string, and calls ObjectStateFormatter to deserialize:

protected override object LoadPageStateFromPersistenceMedium()
{
    object viewStateBag;

    string file = GetFileName();
    try {
        StreamReader sr = new StreamReader(file);
        string m_viewState = sr.ReadToEnd();
        sr.Close();
    }
    catch {
        throw new HttpException("The View State is invalid.");
    }
    ObjectStateFormatter m_formatter = new ObjectStateFormatter();

    try {
        viewStateBag = m_formatter.Deserialize(m_viewState);
    }
    catch {
        throw new HttpException("The View State is invalid.");
    }
    return viewStateBag;
}

To take advantage of this feature to keep view state on the server, you only need to change the parent class of the page code file to inherit from ServerViewStatePage:

public partial class TestPage : ServerViewStatePage
{
}

Figure 3 shows the view-state files created in a temporary folder on the Web server machine.

Figure 3. View state files created on the server. The folder must grant write permissions to the ASP.NET account.

The page shown in Figure 3 enables view state, but no hidden field is present in its client-side code.

Other  
 
Top 10
Review : Sigma 24mm f/1.4 DG HSM Art
Review : Canon EF11-24mm f/4L USM
Review : Creative Sound Blaster Roar 2
Review : Philips Fidelio M2L
Review : Alienware 17 - Dell's Alienware laptops
Review Smartwatch : Wellograph
Review : Xiaomi Redmi 2
Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
REVIEW
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8