Click here to Skip to main content
Click here to Skip to main content

Beginners Introduction to State Management Techniques in ASP.NET

, 23 Dec 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
This article discusses the state management techniques used in ASP.NET. We discuss: QueryString, Cookie, Session, Profile, Static Variables and Application state.

Table of Contents

Introduction

Recently Code Project started a beginners walkthrough for web development, an initiative for organizing all the information required for web development under one article. I think it will be helpful for beginners to get guidelines for web development. This article is my contribution to the ASP.NET section where I describe the state management techniques and best practices used when developing with ASP.NET.

HTTP Protocol and the Need for State Management Techniques

Hyper Text Transfer Protocol (HTTP) is a communication protocol which is implemented in the "World Wide Web(WWW)". It is a request/response style protocol. Clients (browsers, spider, etc) will request to a server (web server) and the server responds to these requests. HTTP uses TCP protocol for communication. It connects to a specific port (default is 80) to the server and communicates via that port. Once the response is received completely, client programs will be disconnected from the server. For each request, client programs have to acquire a connection with servers and do all the request cycles again.

ASP.NET files are just text files which will be placed in the server and served upon the request. When a request comes for a page, the server will locate the requested file and ask the ASP.NET engine to serve the request. The ASP.NET engine will process the server tags and generate HTML for it and return back to the client. HTTP is a stateless protocol and the server will abandon the connection once the request is served.

Since HTTP is stateless, managing state in web applications is challenging. State management techniques are used to maintain user state throughout the application. Managing state in a stand-alone application is trivial as they don't have a request/response nature. Information you want to maintain over the lifetime of a web applications depends on your context. It can be from simple numbers to very complex objects.

Understanding the state management techniques play a major role in creating efficient web applications. ASP.NET is very rich in state management techniques. The following are the commonly used state management techniques.

  • QueryString
  • Cookies
  • Cache
  • ViewState
  • Session state
  • Application state
  • Static variables
  • Profiles

Cache and ViewState are already explained in the previous sections and this article will not cover it.

QueryString

This is the most simple and efficient way of maintaining information across requests. The information you want to maintain will be sent along with the URL. A typical URL with a query string looks like

 www.somewebsite.com/search.aspx?query=foo

The URL part which comes after the ? symbol is called a QueryString. QueryString has two parts, a key and a value. In the above example, query is the key and foo is its value. You can send multiple values through querystring, separated by the & symbol. The following code shows sending multiple values to the foo.aspx page.

 Response.Redirect("foo.aspx?id=1&name=foo");

The foo.aspx page will get the values like in the following table.

Key Value
id 1
name foo

The following code shows reading the QueryString values in foo.aspx

 string id = Request.QueryString["id"];
 string name = Request.QueryString["name"];

Request.QueryString has two overloaded indexers. One accepts the key name and another a zero-based index. The latter is useful when you don't know the query string names. If you try to get a value which is not in the QueryString collection, you will get a NULL reference.

QueryString Encoding

The URL RFC [^] states that, a URL can have only ASCII characters. So all the other characters should be encoded when you pass through the URL. The .NET Framework provides the HttpServerUtility.UrlEncode class to encode the URL.

The following code shows how name and id is passed to foo.aspx page as encoded.

  string id = "1";
  string name = "foo#";
  string url = string.Format("foo.aspx?{0}&{1}", Server.UrlEncode(id), Server.UrlEncode(name));
  Response.Redirect(url);

  // decoding can be done using it's counter part HttpServerUtility.UrlDecode()

  string id = Server.UrlDecode(Request.QueryString["id"]);
  string name = Server.UrlDecode(Request.QueryString["name"]);

Note: HttpServerUtility is available to your code in all webforms through the Page.Server property. Also you only need to encode those values which have non-ASCII characters, not all the values.

Reading QueryString Safely

I have seen many people use code as shown below to read values from a QueryString collection

 
  // Bad practice - Don't use!
  Request.QueryString["id"].ToString();

This is hilarious. Request.QueryString[key] returns a string and has no need to convert it again to string. Another problem with the above code is, Request.QueryString[key] will return NULL if the specified key not found in the collection. In such cases, calling Request.QueryString[key].ToString() will lead to a NullReferenceException. The following code shows reading a QueryString value safely.

  string queryStringValue = Request.QueryString["key"];
  if (string.IsNullOrEmpty(queryStringValue)) {
      // querystring not supplied. Do necessary action
  }
  else
      // Querystring supplied. continue execution

Pros and Cons

Query string is lightweight and will not consume any server resources. It is very easy to use and it is the most efficient state management technique. However, it has many disadvantages.

  • You can pass information only as a string. If you need to pass objects in any case through QueryString, methods explained in this excellent article [^] will work. But it involves more effort.
  • URL length has limitations. So you can't send much information through URL.
  • Information passed is clearly visible to everyone and can be easily altered.

Producing Hackable URLs

URLs should be hackable, which means that, a user should be able to easily navigate from page to page by modifying the QueryString values. But you need to make sure that your website's security is not getting compromised by implementing this. A good example for hackable URLs is on MSDN. Consider the following

 // System.Object classes documentation for .NET 1.1
 http://msdn.microsoft.com/en-us/library/system.object(VS.71).aspx 

 // System.Object classes documentation for .NET 2.0. Just change the 71 to 80
 http://msdn.microsoft.com/en-us/library/system.object(VS.80).aspx

This helps users to navigate between pages more easily.

Securing QueryString

Since values in QueryString can be tampered easily, it is a programmer's job to ensure that it has valid values. You might be wondering, if QueryString is insecure, then why try to secure it instead of using some secure state management techniques? In some cases, you can't avoid using QueryString and you will be forced to send sensitive information through that. Consider a user email validation system. When user registers, the system will send a mail with a link to activate the user account. In this case, we have to pass some identification for the user account along with the URL. Since user account information is sensitive, we have to encrypt the QueryString value in the email validation link.

Consider a Edit.aspx?pid= page which allows to edit your personal details. You need to ensure the person id supplied has a valid type, integer in this case. The following code shows how this is done

  string queryStringValue = Request.QueryString["pid"];
  if (string.IsNullOrEmpty(queryStringValue)) {
      // querystring not supplied. Do necessary action
  }
  else {
      // Querystring supplied. continue execution
      int personId;
      if(!int.TryParse(queryStringValue,out personId))
           // invalid type specified. Alert user
  }

Then you may need to check whether the currently logged user is authorized to edit this record.

 int personId;
 if (int.TryParse(queryStringValue, out personId)) {
        // check the edit permissions here
 }

System.Security.Cryptography namespace has classes which help to encrypt strings. You can pass the encrypted string through the URL, so that it is tamperproof and secure up to a certain extent.

Cookies

A cookie is a small file which is stored in the visitor's hard disk drive. This is helpful for storing small and trivial information. According to the RFC [^] , a cookie can have a maximum size of 4KB. The web server creates a cookie, attaches an additional HTTP header to the response, and sends it to the browser. The browser will then create this cookie in a visitor's computer and includes this cookie for all further requests made to the same domain. Servers can read the cookie value from the request and retain the state.

The server adds the following to the HTTP header for creating a cookie

  Set-Cookie: key=value

The browser reads the above value and creates cookies at the user's end. It adds the cookie value to the request like

  Cookie: key=value

Note: The location where the cookie is stored is completly controlled by the browser. Sometimes it may keep the cookie in its memory instead of creating a file.

Creating and using a cookie is trivial in ASP.NET. The HttpCookie class is a key/value collection which allows storing string values. The following code shows how to create a cookie and send it to the client. Cookies are added using Response property and retrieved using Request.

  Response.Cookies["id"].Value = "10";

Since no expiry time specified, a cookie added like the above method will be cleared by the browser immediately when it is closed. If you would like to keep the cookie for a long time, you have to use the HttpCookie.Expires property set with an expiration date. The following code shows how to do that.

  // this cookie expires after one day from the date it is set
  // browser will take care about removing the cookies after the expiry time
  Response.Cookies["id"].Value = "10";
  Response.Cookies["id"].Expires = DateTime.Now.AddDays(1);

Once you set the cookie, the browser will include it for every request. You read the cookie from the Request.Cookies collection by specifying cookie name. Consider the following code

  // for safety, always check for NULL as cookie may not exist
  if (Request.Cookies["id"] != null) {
       string userId = Request.Cookies["id"].Value;
       Response.Write("User Id value" + userId);
  }

Cookies are managed by the browser and will take care about removing expired cookies. If you need to remove a cookie before the expiry period, you have to create a cookie with the same name and with an expiry date that is already passed. This will make browser think that the cookie is expired and will be removed immediately. Here is how you do that

  Response.Cookies["id"].Expires = DateTime.Now.AddDays(-1);

Some Useful Properties you Must Know Before Using Cookies

Property name Description
Domain Specifies which domain is associated with this cookie. Default is the current domain. See security constraints later in this article
Expires A DateTime value specifies the expiry time of the cookie
HttpOnly Cookies can be accessed using java script. Setting this property prevents cookies being accessed from java script
Secure Set this if cookies are transmitted over SSL
Name Cookie name
Value Cookie value (string)

Multi-valued Cookies

RFC states that a browser should not store more than 20 cookies from a domain. Multi-Valued cookie is very handy when you have more items to keep in cookie. To create a multi-valued cookie, you instantiate the HttpCookie instance and set it's values. Consider the following code

  HttpCookie cookie = new HttpCookie("user");
  cookie["name"] = "Foo";
  cookie["age"] = "22";
  cookie.Expires = DateTime.Now.AddDays(1);
  Response.Cookies.Add(cookie);

Here is how you read it

  HttpCookie cookie = Request.Cookies["user"];
  // for safety, always check for NULL. If cookie doesn't exist, it will be NULL
  if (cookie != null) {
      string name = cookie["name"];
      string age = cookie["age"];
  }
  else
     // Cookie not exist

A Practical Example

You might have noticed the "Remember me next" time option in most of the websites. This is done using cookies. The following steps will be involved when you choose this option.

  • When the user checks the "Remember me next time" option, create a cookie with a value to identify the user (eg: user id).
  • When the page loads, check for cookie existence. If it exists, read the cookie value.
  • Authenticate the value and create a session.

Security Constraints

Since cookies are stored in the visitors computer, to prevent it from harming the system, browsers ensure some security constrains to cookies. THe following points explain the security constraints:

  • Cookies are specific to domains, which mean that a cookie set from "DomainA" is not accessible to "DomainB". Browsers store the domain with each cookie and will ensure it won't be sent to another domain.
  • Other restriction is in size. Browsers will not allow storing cookies for more than 4KB from a domain.
  • Browsers provides the option to disable cookies

Proper design of the application can avoid malicious attacks through cookies. Consider a website which sets the current user id in a cookie for retaining the user account information in subsequent visits. Since the cookie is kept in the visitor's system as plain text, the user can always goto the folder where the cookie is kept and change the user id to some other value. When the website is requested again, it will use the new user id which will give the hacker access to the new account.

While cookies are mostly used for storing account information, they are really not intended for such use. You should always take precautions to avoid hacks like the above by encrypting the values before keeping in cookie.

Pros and Cons

A cookie is a very handy and easily usable state management technique. It is useful when you want to keep small information that is needed for long periods of time. The processing overhead of cookies is much less compared to sessions. However, it has the following disadvantages:

  • Cookies have a size limitation of 4KB. Storing huge information is not possible.
  • Cookies can be easily tampered as they are kept in the client's machine. So additional security checking has to be done when using them.
  • The user can disable cookies.

Session State

A cookie is very simple and is not suitable for sophisticated storage requirements. Session state is a workaround for this problem and it gives a method to keep more complex objects securely. ASP.NET allows programmers to keep any type of objects in session. Data stored in session will be kept in server memory and it is protected as it will never get transmitted to a client. Every client that uses the application will have separate sessions. Session state is ideal for storing user specific information.

The following code shows storing a string value in session.

 Session["name"] = "Navaneeth";

Session accepts a System.Object type. So you need a type cast when reading. Reading values from session is like

 string name = Session["name"] as string;
 // null checking is needed as session may not exist
 if(!string.IsNullOrEmpty(name))
      // use the name here

Values stored in sessions can be removed by several methods. The following table shows different methods used.

Method Description
Session.Abandon() Cancels the session and fires end event. This is used when you are done with the session.
Session.Clear() / Session.RemoveAll() Clears all contents of the session. This will not end the session
Session.Remove(string) Removes the session name supplied.

How Session Works?

ASP.NET maintains a unique id which is called as "session id" for each session. This id is generated using a custom algorithm and it is unique always. Session id will be sent to the client as a cookie and the browser resends this upon each request. ASP.NET uses this session id to identify the session object. The following code shows how to get the session id

 string sessionId = Session.SessionID;

If you haven't stored anything in the session, ASP.NET will generate a different session id for each request. Once a session has contents, the session id will not change. Session id is the only information which is sent to the client about sessions. As said before, ASP.NET sends session id in a cookie named ASP.NET_SessionId. But this will not work if cookies are disabled by the visitor. In such cases, ASP.NET passes session id through the URL. This behaviour can be controlled by adding the following section to web.config file under the system.web section.

<sessionState 
      cookieless="UseUri" />
Cookieless session

Note: ASP.NET AJAX extensions won't work as expected if this is enabled.

Session Timeout

Each session will have a timeout value (default 20Mins). If the page is not getting any requests within the timeout limit specified, ASP.NET will assume that the user has left the application and it immediately terminates the session and fires the End event. This helps the server to cleanup unused sessions and gives room for new requests. Timeout value can be changed from web.config file or through code. Timeout value is specified in minutes.

 <sessionState 
        timeout="60" />

 or

 Session.Timeout = 60;

Session Timing out Frequently

I have seen many questions on discussion forums which state, "My session timeout is 60 minutes and it is timing out before that." Well, ASP.NET will clear session when any of the following happens

  • ASP.NET worker process recycles frequently. When this happens, it will clear all active sessions.
  • When files like web.config or application assemblies are modified, ASP.NET will recyle the worker process.

Where Session is Stored?

ASP.NET allows three types of session storage which are described below

Mode Configuration Storage location Description Pros/Cons
InProc <sessionState mode="InProc" /> ASP.NET processes memory area This is the default session storage. Session data will be kept in the server memory. InProc mode is a high performant as it reads from the same processes memory and it allows you to keep all .NET types. If session mode is not specified, ASP.NET will use InProc as the default mode. As the InProc mode keeps data in same processes memory area, any impacts happened for the ASP.NET worker process will affect the session data.
StateServer
<sessionState
mode="StateServer"
stateConnectionString= "tcpip=Yourservername:42424" /> 
Server memory as a seprate process StateServer mode provides a basic level of isolation for the data storage. It runs as a separate windows service and keeps the session data out of ASP.NET process memory area. To access session, ASP.NET process has to communicate with this external process. It is less performant compared to InProc mode. But this helps you to avoid loosing session data when ASP.NET worker process restarts.
SQL Server <sessionState mode="SQLServer" sqlConnectionString="..." /> In SQL server database If you still need more resillient storage, SQLServer mode is the choice. It allows to keep session data in SQLServer. This is helpful when your web application is hosted in a webfarm.
  • Slow data access
  • Allows to store only serializable types

If any of the above discussed methods are not satisfying your storage requirements, ASP.NET allows to specify a custom storage provider. This [^] article shows how to do this.

Usage and Best Practices

Incorrect usage of session will blow up your application. The most common error users make is the NULL reference exceptions when using sessions. Consider the following code

  // bad code ! don't use
  string name = Session["name"].ToString();

This code is problematic as session["name"] may not exist or may be NULL and ToString() will be called on that NULL reference which will throw the common "Object reference not set to an instance of the object" error.

Another problem with session is that it is not strongly typed. Session keeps System.Object type which means every .NET type can be kept in session. Consider the following code

 Session["age"] = "I can store a value that is not number!";

Since it is not strongly typed, Session["age"] can contain any value and you will have problems when using this. Also, you may make typing mistakes when typing the session names. This will also lead to unexpected behaviours. The following section describes workarounds for these problems.

Wrapping Session in a Strongly Typed Class

To workaround the above problems, we can create a strongly typed wrapper classes around the session and route all calls to session through this wrapper. Consider a simple scenario where you need to keep user details like name, age, email validated etc in a session. We create a class to represent all required fields. See the following code

 public class PersonSession
 {
    // This key is used to identify object from session
    const string KEY = "personDetails";

    public PersonSession(int id,string name,int age,bool emailValidated)
    {
        this.Id = id;
        this.Name = name;
        this.Age = age;
        this.HasEmailValidated = emailValidated;
    }

    public static PersonSession GetPersonSession() {
        return HttpContext.Current.Session[KEY] as PersonSession;
    }

    public static void CreatePersonSession(PersonSession person) {
        HttpContext.Current.Session[KEY] = person;
    }

    public int Id { get; private set; }
    public string Name { get; private set; }
    public int Age { get; private set; }
    public bool HasEmailValidated { get; private set; }
 }

The above given class abstracts the session access and provides a clear interface to access the session contents safely. The static methods CreatePersonSession and GetPersonSession can be used to create and get details of a person from session. The following code shows how to store person details into session.

 PersonSession person = new PersonSession(int.Parse(txtPersonId.Text),
            txtName.Text, int.Parse(txtAge.Text), chkEmailValidated.Checked);
 PersonSession.CreatePersonSession(person);

To retrieve person details, you need to do

 PersonSession person = PersonSession.GetPersonSession();
 // if session not exist, this will return NULL
 if (person != null) {
    // person exist. Use person's properties to get values
 }

Note: HttpContext.Current.Session is needed when accessing from a class that is not derived from System.Web.UI.Page.

Base Page Class Approach

Assume that you need to prevent users from seeing your page unless person details exists in session. You may end up doing the following code for all the pages that needs to be secured.

 protected void Page_Load(object sender, EventArgs e)
 {
        PersonSession person = PersonSession.GetPersonSession();
        // if session not exist, this will return NULL
        if (person == null) {
            // session not exist. Redirect user to login page
        }
 }

Writing the above code in all pages that needs session is redundant. It is very tough to make a change if something got changed in the session wrapper class-PersonSession. The recommended approach is to keep a base page class which is derived from System.Web.UI.Page and all your pages which need PersonSession should inherit from this base page class. This allows you to do the session checking in the base class and redirect the user if required. The following diagram shows this approach.

We create two classes NormalPage and SecuredPage both derived from System.Web.UI.Page. SecuredPage overrides the OnInit method which looks like this:

 protected override void OnInit(EventArgs e) {
        base.OnInit(e);
        // check the person details existance here
        PersonSession person = PersonSession.GetPersonSession();
        if (person == null) {
            Response.Redirect("NotLogged.aspx");
        }
        else
            this.Person = person;
 }

If person details are not found in the session, it redirects to the NotLogged.aspx page and it sets the Person property if session exists. Classes which derive from this class can use this Person property to access the person details. Usage of this class is pretty straightforward. See the following code.

 public partial class AuthenticatedPage : SecuredPage
 {
    protected void Page_Load(object sender, EventArgs e)
    {
        lblMessage.Text = "Session exist";
        lblMessage.Text += string.Format("Person Id : {0}",Person.Id);
        lblMessage.Text += string.Format("Person Name : {0}", Person.Name);
        lblMessage.Text += string.Format("Person Age : {0}", Person.Age);
        lblMessage.Text += string.Format("Email validated? : {0}", Person.HasEmailValidated);
    
    }
 }

Note: We are not using NormalPage here. If you have any particular behaviour common for all non-authenticated pages, this class is the best place to add that.

That's all about sessions. When using it, try not to abuse sessions. Overusing sessions may degrade your application performance.

Application State

ASP.NET implements application state using the System.Web.HttpApplicationState class. It provides methods for storing information which can be accessed globally. Information stored on application state will be available for all the users using the website. Usage of application state is the same as sessions. The following code shows storing a value in an application variable and reading from it.

 Application["pageTitle"] = "Welcome to my website - ";

 // Reading the value from application variable
 string pageTitle;
 if (Application["pageTitle"] != null)
      pageTitle = Application["pageTitle"].ToString();

Understanding Session and Application Events

Before we discuss the practical usage of application state, you should get a basic knowledge about the events associated with application and session. These events can be seen in the global.asax file. See the following table for the details.

Event name Description
Application_Start This event executes when application initializes. This will execute when ASP.NET worker process recycles and starts again.
Application_End Executes when the application ends.
Session_Start Executes when a new session starts.
Session_End Executes when session ends. Note : this event will be fired only if you are using InProc as session mod.

A Practical Example

The most common usage of application variables is to count the active number of visitors that are browsing currently. We can utilize session_start and session_end events to do this. The following code shows how this is done.

 void Application_Start(object sender, EventArgs e) 
 {
     // Application started - Initializing to 0
     Application["activeVisitors"] = 0;

 }
 
 void Session_Start(object sender, EventArgs e) 
 {
     if (Application["activeVisitors"] != null) {
         Application.Lock();
         int visitorCount = (int)Application["activeVisitors"];
         Application["activeVisitors"] = visitorCount++;
         Application.UnLock();
     }
 }

You might have noticed Application.Lock() and Application.UnLock() calls. ASP.NET is multithreaded and this is required to synchronize data when multiple visitors access the site at the same time.

Application state is not providing any timeout method like session. Application state will be available until the application ends. So one should be very careful when using application state. You should explicitly cleanup the values stored when you are finished using it.

Keeping State in Static (shared in VB) Variables

Static variables will have a lifetime until the application domain where it is hosted ends. ASP.NET hosts each website in a separate application domain to provide isolation with other websites hosted on the same server.

Consider you have a page where all product details are displayed. Product details are fetched from the database and filled into custom collection and returned back to the page. To avoid fetching product details all time for each visitors, we can load it when it is requested for the first time and keep it in a static variable to serve for the next requests. Consider the following Product and ProductServices class.

 class Product
 {
        public Product(int id,string name) {
            this.Id = id;
            this.Name = name;
        }
        public int Id { get; private set; }
        public string Name { get; private set; }
 }

 class ProductService
 {
        static List<Product> products = null;
        static readonly object locker = new object();

        public static List<Product> GetAllProducts() {
            // If product is NULL, loading all products and returning
            if (products != null) {
                lock (locker) {
                    if (products != null) {
                        // fill the products here
                    }
                }
            }
            return products;
        }
 }

The above given code is self explanatory. The variable products will have a lifetime until the application domain unloads. When ProductService.GetAllProducts() is called for the first time, it fills the collection and return. For the further requests, it will just return the collection which is already filled.

Values kept in static variables are accessible to all visitors in the website. So you should take extra care when writing methods like the above. You need locking because multiple visitors may call the GetAllProducts method at the same time.

The above given example is an implementation of the " Singleton pattern [^] ".

Profiles

Session data is lost when the visitor leaves the webpage. What if you need to persist all the user information for a long time? ASP.NET Profile is the answer. It provides a neat way to persist information for a long time. Creating a profile is trivial. You only need a few entries in the web.config file as seen below

 <profile>
    <properties>
       <add name="Id" type="Int32"/>
       <add name="Name"/>
       <add name="Age" type="Int32"/>

    </properties>
 </profile>

ASP.NET generates a strongly typed class for accessing profile data. Data type for the properties are chosen depending upon the type value. Default type is string if no type is specified. Following code shows setting values and reading back from profile.

 Profile.Name = txtName.Text;
 Profile.Id = int.Parse(txtPersonId.Text);
 Profile.Age = int.Parse(txtAge.Text);

 // to read profile value, use

 int age = Profile.Age;
 string name = Profile.Name;
 int id = Profile.Id;

ASP.NET keeps the profile data in SQLServer database. If no databases are available in the project, it creates a database file in the app_data directory when it is used for the first time. Profiles are implemented using the provider pattern. SQLProfileProvider is the default profile provider. Profiles use windows authentication by default. Profile object can be used with any authentication modes supported by ASP.NET.

Profile is very handy in many situations. However, it has the following drawbacks

  • It allows to keep only serializable types
  • Reading data from profile requires database access which can potentially make your application less performant. If your website uses profiles heavily, you have to cache the results to avoid unncessary database calls.
This is a high level overview of profile. There are many other features profile offers such as groups, anonymous access etc. Explaining whole profile detail is beyond the scope of this article. Check this [^] MSDN article for more details.

Hacking ViewState

ViewState is already explained in the previous section [^] . Articles that talk about viewstate always say, it is less secure and not good for keeping secure information. Let us see how a viewstate value can be hacked.

Data kept in Viewstate is serialized using LosFormater, a less known class used for serialization. LosFormatter is helpful to serialize simple types and it produces ASCII string representation of the object graph. The following code shows using LosFormatter.

  [Serializable]
  class Customer
  {
       public Customer(int age,string name) {
           this.Age = age;
           this.Name = name;
       }
       public int Age { get; set; }
       public string Name { get; set; }
  }
  
  string Serialize() {
        
     // Creating customer object
     Customer customer = new Customer(25,"Navaneeth");

     // formatting
     LosFormatter formatter = new LosFormatter();
     using (StringWriter output = new StringWriter()) {
        formatter.Serialize(output, customer);
        return output.ToString();
     }
  }

The above code serializes the object graph and produces an ASCII string which can be transmitted over HTTP.

The following code shows decrypting viewstate values.

  object HackViewstate(string viewStateValue) {
        LosFormatter formatter = new LosFormatter();
        return formatter.Deserialize(viewStateValue);
  }

The following figure shows the contents of the object which is deserialized

This gives you a clear explanation of why secured data should not be kept on viewstate.

Conclusion

This article tackled the state management techniques used in ASP.NET. You have learned what is HTTP protocol and the need for state management. We discussed the stateless architecture of HTTP protocol and how a website works.

In the second section, we discussed QueryString and how it helps to maintain information across different pages. We also discussed about hackable URLs and some best practices for using it.

The third section discussed the usage of cookies. We have seen the pros and cons of cookies. We also discussed multi-valued cookies which helps to overcome the number of cookies a website can set. Security constraints and a practical example have also been discussed.

The next section discussed "Session state" which provides more sophisticated storage. We have seen how session works, session modes and best practices for using it. We have also discussed about session timeout and cookie-less sessions.

"Application state" is discussed in the next section. Discussed about the events which are associated with session state and application state. We have seen a practical example where application state is very handy. Then we discussed about storing the state in static(shared in VB) variables. We have seen the lifetime of a static variables and how locking is used to synchronize access between multiple threads. Profiles are very handy when you need to persist information for long periods of time. We have discussed profiles in the next section and seen simple usage of profiles.

Finally, we discussed viewstate hacking techniques and proved secured information should not be kept on viewstate. We discussed about the serialization class LosFormatter and how it works.

That's all about this article. I hope you will find it helpful. I'd appreciate if you rate this article and leave your feedback below.

Thank you for reading, happy coding!

History

  • 23rd December - Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

N a v a n e e t h
Software Developer ThoughtWorks
India India
Call me Navaneeth Some years ago--never mind how long precisely, I was doing programs with C and C++. When .NET came, I started with C#,ASP.NET and SQL Server.

Comments and Discussions

 
GeneralMy vote of 5 PinmemberGabriel Espinoza16-Sep-13 11:25 
GeneralMy vote of 5 Pinprofessionalketan italiya11-Sep-13 2:00 
QuestionThanks.. PinmemberRoshanthapa198525-Jun-13 22:13 
QuestionSummarize PinmemberPeace ON27-Mar-13 7:37 
QuestionSummarize PinmemberPeace ON27-Mar-13 7:36 
GeneralMy vote of 5 PinmemberMohammed.Gafoor26-Mar-13 2:16 
GeneralMy vote of 4 Pinmembertariq_6193-Jan-13 7:30 
GeneralMy vote of 5 Pinmembersam viper14-Sep-12 7:57 
QuestionHelpfull Article!! PinmemberPradnya K17-Jun-12 7:48 
QuestionNice artical Pinmemberunikela18-May-12 18:11 
GeneralMy vote of 4 Pinmemberomvikram13-May-12 0:26 
GeneralMy vote of 4 PinmemberRamakantaSahoo4-May-12 2:52 
GeneralMy vote of 4 Pinmemberashvin.kumar0123-Nov-11 21:44 
QuestionState management ASP.NET Pinmemberawadhendra tiwari27-Aug-11 2:17 
GeneralMy vote of 1 PinmemberMember 80679577-Jul-11 23:29 
GeneralMy vote of 5 PinmemberM.Farrukh Abbas14-Feb-11 18:23 
GeneralMy vote of 5 Pinmemberchriram9-Oct-10 5:42 
GeneralMy vote of 3 Pinmembersiva varri29-Jul-10 10:14 
GeneralState Management Techniques in ASP.NET Pinmembersuman kumar keshri29-Jun-10 3:31 
GeneralBeginners Introduction to State Management Techniques in ASP.NET Pinmemberjonanirina14-Jun-10 23:22 
GeneralAlso Nice One Pinmemberthatraja15-Jan-10 11:18 
GeneralRe: Also Nice One PinmvpN a v a n e e t h16-Jan-10 5:26 
Generalhi PinmemberVivek Thakur25-May-09 9:26 
GeneralRe: hi PinmvpN a v a n e e t h25-May-09 16:10 
Generalthanx, one problem Pinmembermark_me25-Apr-09 14:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.141015.1 | Last Updated 23 Dec 2008
Article Copyright 2008 by N a v a n e e t h
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid