ASP.NET ViewState Tips and Tricks #2

If you need to store complex types in ViewState DO implement IStateManager to control view state persistence and reduce its size. By default a serializable object will be fully stored in view state using BinaryFormatter.

A quick comparison for a complex type with two integers and one string property produces the following results measured using ASP.NET tracing:

BinaryFormatter: 328 bytes in view state
IStateManager: 28 bytes in view state

BinaryFormatter sample code:

// DO NOT
[Serializable]
public class Info
{
    public int Id { get; set; }

    public string Name { get; set; }

    public int Age { get; set; }
}

public class ExampleControl : WebControl
{
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        if (!this.Page.IsPostBack)
        {
            this.User = new Info { Id = 1, Name = "John Doe", Age = 27 };
        }
    }

    public Info User
    {
        get
        {
            object o = this.ViewState["Example_User"];

            if (o == null)
                return null;

            return (Info)o;
        }
        set { this.ViewState["Example_User"] = value; }
    }
}

IStateManager sample code:

// DO
public class Info : IStateManager
{
    public int Id { get; set; }

    public string Name { get; set; }

    public int Age { get; set; }

    private bool isTrackingViewState;

    bool IStateManager.IsTrackingViewState
    {
        get { return this.isTrackingViewState; }
    }

    void IStateManager.LoadViewState(object state)
    {
        var triplet = (Triplet)state;

        this.Id = (int)triplet.First;
        this.Name = (string)triplet.Second;
        this.Age = (int)triplet.Third;

    }

    object IStateManager.SaveViewState()
    {
        return new Triplet(this.Id, this.Name, this.Age);
    }

    void IStateManager.TrackViewState()
    {
        this.isTrackingViewState = true;
    }
}

public class ExampleControl : WebControl
{
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        if (!this.Page.IsPostBack)
        {
            this.User = new Info { Id = 1, Name = "John Doe", Age = 27 };
        }
    }

    public Info User { get; set; }

    protected override object SaveViewState()
    {
        return new Pair(
            ((IStateManager)this.User).SaveViewState(),
            base.SaveViewState());
    }

    protected override void LoadViewState(object savedState)
    {
        if (savedState != null)
        {
            var pair = (Pair)savedState;

            this.User = new Info();

            ((IStateManager)this.User).LoadViewState(pair.First);

            base.LoadViewState(pair.Second);
        }
    }
}
About these ads
Leave a comment

1 Comment

  1. Tom

     /  March 8, 2012

    What a big difference! Thanks, I was not aware of this, very usefull.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 27 other followers