ASP.NET ViewState Tips and Tricks #2
- by João Angelo
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);
}
}
}