Search code examples
asp.netviewstate

Why is my UserControl's ViewState partially saved?


I have a user control that makes substantial use of this.ViewState["Key"] = SomeValue. Most of it is loaded from my Page_Init():

protected void Page_Init(object sender, EventArgs e)
{
    if(!IsPostBack)
    {
         ViewState["Blahblah"] = LoadSomeValue();
    }
}

The rest are set at various points.

But for some reason it's unavailable on subsequent postbacks. I overrode SaveViewState() to check, and only like three of them are saved!

protected override object SaveViewState()
{
    List<object> viewStateObjectsBefore = ViewState.OfType<object>().ToList();

    object ret = base.SaveViewState();

    List<object> viewStateObjectsAfter = ViewState.OfType<object>().ToList();
    GC.KeepAlive(viewStateObjectsBefore);
    GC.KeepAlive(viewStateObjectsAfter);
    GC.KeepAlive(ret);
    return ret;
}

Both viewStateObjectsBefore and viewStateObjectsAfter contain 10 key/value pairs, but ret only contains three!

Added: Moving the initializations to Page_Load() is not an easily available option, because the initializations must be done before the parent's Page_Load() executes.


Solution

  • Adding a call to SetDirty() at the end of my Page_Init() solved the problem:

    protected void Page_Init(object sender, EventArgs e)
    {
        if(!IsPostBack)
        {
            ViewState["Blahblah"] = LoadSomeValue();
    
            //Looks like the ViewState is not yet "tracking" changes before Page_Load.
            //The items have to be marked as "dirty" manually so they'll be included by SaveViewState().
            ViewState.SetDirty(true);
        }
    }