CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Brendan Tompkins [MVP]

Blog First. Ask Questions Later.

A Strongly-Typed Cookie State Object

A couple of weeks ago, I posted about A Better ASP.NET State Pattern, which essentially demonstrates a strongly-typed wrapper base class for storing ASP.NET state.  In this post, I showed one implementation of this pattern, which used Session to store the state.  I hinted that it would be easy to use other back end storage mechanisms for your state objects:

Note that you can create one that stores state in ViewState, or Application or Cache or in the Database, or on your cell phone. The point is, you just derive from StateBase, and implement the abstract methods.

This week I’m going to do a series of three posts to demonstrate different back end storage mechanisms for storing Page State in Cookies, Cache, and ViewState.  Today, I’m going to start with a Strongly-typed cookie wrapper class, called CookieStateObject.

  [Serializable]

  public abstract class CookieStateObject : StateBase

  {

    public CookieStateObject()

    {

    }

 

    protected System.DateTime expires = System.DateTime.Now.AddYears(1);

 

    /// <summary>

    /// Creates a new <see cref="ViewStateObject"/> instance.

    /// </summary>

    /// <param name="stateKey">State key.</param>

    public CookieStateObject(string stateKey) : base(stateKey)

    {}

 

    /// <summary>

    /// Stores this instance.

    /// </summary>

    /// <returns></returns>

    public override void Store()

    {

      string serializedVersion = SerializationHelper.XmlSerialize(this);

      System.Web.HttpContext.Current.Response.Cookies[stateKey].Value = System.Web.HttpUtility.UrlEncode(serializedVersion);

      System.Web.HttpContext.Current.Response.Cookies[stateKey].Expires = expires;

    }

 

    /// <summary>

    /// Removes this instance.

    /// </summary>

    /// <returns></returns>

    public override void Remove()

    { 

      System.Web.HttpContext.Current.Response.Cookies.Remove(stateKey);

    }

 

    /// <summary>

    /// Restores this instance.

    /// </summary>

    /// <returns></returns>

    public override Object Restore()

    {

      if(System.Web.HttpContext.Current.Request.Cookies[stateKey] != null)

      {

        string serializedVersion = System.Web.HttpContext.Current.Request.Cookies[stateKey].Value;

        return SerializationHelper.XmlDeSerialize(System.Web.HttpUtility.UrlDecode(serializedVersion), this.GetType());

      }

 

      return null;

    }

  }

This class Serializes the object to XML, UrlEncodes the XML, and stores it as a cookie.  You can get a copy of An XML Serialization Helper Class here.  Here’s an example of an implementation of the CookieStateObject:

    public class CameraState : CookieStateObject

    {

 

      /// <summary>

      /// Creates a new <see cref="CameraState"/> instance.

      /// </summary>

      public CameraState() : base("Camera_STATE")

      {}

 

      private ArrayList m_arrCameraID = new ArrayList(); 

      private  ImageWidth m_imaCameraImageWidth = ImageWidth.Small;

 

      /// <summary>

      /// Gets the instance.

      /// </summary>

      public new CameraState Instance

      {

        get { return (CameraState) base.Instance; }

      }

 

      public ImageWidth CameraImageWidth

      {

        get

        {

          return m_imaCameraImageWidth;

        }

        set

        {

          m_imaCameraImageWidth = value;

        }

      }

 

      public ArrayList CameraIDs

      {

        get

        {

          return m_arrCameraID;

        }

        set

        {

          m_arrCameraID = value;

        }

      }

    }

And here’s an example of how this class can be used:

    private CameraState state = new CameraState(); 

 

    private void AddSelectedToView()

    {

      this.state.Instance.CameraIDs.Clear();

 

      foreach(ListItem item in this.chkCameras.Items)

      {

        if(item.Selected)

        { 

          this.state.Instance.CameraIDs.Add(item.Value);

        }

      }

 

      this.state.Instance.CameraImageWidth = ImageWidth.Thumbnail;

      this.state.Instance.Store();

    }

A couple of things to note here.  Cookies have a maximum size of 4KB.  My Serialized, UrlEncoded Camera object above is about 1.3K when filled with the maximum amount of data that I expect it to ever hold.  You should be very aware of this maximum, and make sure you’re well below it in practice, however this is true of any data you intend to store, no matter where you decide to persist it.   If you run into space limitations, you can tweak the serialized Xml using attributes. 

Using a strongly-typed wrapper for state objects can greatly reduce runtime errors, and make your code easier to read and mantain over time.  Hope you find this useful!

-Brendan 



Comments

David Hayden said:

Sigh...

I am trying to print your post so I can read it later tonight off-line and your scrollbar magic is keeping all the code from printing.

Is there anyway you can provide a printable version for people like me who like to print these good examples for late night reading?
# March 15, 2005 8:48 AM

Brendan Tompkins said:

Sorry David! I tried adding an @print style, but I couldn't get it to work, so I abandoned the scrollbars alltogether.

-B
# March 15, 2005 9:12 AM

TrackBack said:

# March 16, 2005 7:21 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Brendan Tompkins

Brendan has been programming with .NET since the first public beta and is owner and operator of Port Technology Services, a consultancy company providing .NET application development services to the Maritime industry. In July, 2007, he was awarded the Microsoft MVP award for ASP.NET. He's also a proud co-founder of failed .COM startup Intrinsigo, and has had a hand in the failure of numerous other businesses. He currently runs CodeBetter.Com and Devlicio.us, and lives in Norfolk, Virgina with his wife Tiara and son Ian.

View Brendan's profile on LinkedIn

Check out Devlicio.us!

Our Sponsors