How to Serialize a ASP.NET UserControl

asp.netgridviewserializableuser-controlsviewstate

I have a application with a GridView, this GridView have, in your PagerTemplate, a GridViewPager which is an UserControl.

Now I'm trying to store this GridViewPager in a ViewState and I'm having a problem with serialization. Asp.Net tell me that the class is not marked as serializable. I try to mark it as serializable, like this:

namespace Avalon.View.UserControls.Pagers
{
    [Serializable]
    public partial class GridViewPager : System.Web.UI.UserControl
    {
        private GridView _gridView;
        public event EventHandler OnTextPageChanged;

        // Methods, properties...
    }
}

But it dont work

My code is simply, let's see:

// Get and set the GridViewPager to ViewState
public partial class ChamadoList : System.Web.UI.UserControl
{
    // Here a Get and set my GridViewPager into ViewState
    public GridViewPager gvp
    {
        get { return ((GridViewPager)ViewState["GridViewPager"]); }
        set
        {
            if (value == null)
                ViewState["GridViewPager"] = null;
            else
                ViewState["GridViewPager"] = value;
        }
    }

    // Looping in a grid View i get the GridViewPager and put it on ViewState
    protected void gvListaChamados_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        // Here a get the pager 
        if (e.Row.RowType == DataControlRowType.Pager)
        {
            gvp = (GridViewPager)e.Row.FindControl("GridViewPager1");
        }
    }

    //...
}

And here is the error

Server Error in '/' Application.

Type 'ASP.view_usercontrols_pagers_gridviewpager_ascx' in Assembly 'App_Web_epwoiz7x, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Runtime.Serialization.SerializationException: Type 'ASP.view_usercontrols_pagers_gridviewpager_ascx' in Assembly 'App_Web_epwoiz7x, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[SerializationException: Type 'ASP.view_usercontrols_pagers_gridviewpager_ascx' in Assembly 'App_Web_epwoiz7x, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.]
System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) +7733643
System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) +258
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +111
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) +161
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) +51
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +410
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +134
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph) +13
System.Web.UI.ObjectStateFormatter.SerializeValue(SerializerBinaryWriter writer, Object value) +845

[ArgumentException: Error serializing value 'ASP.view_usercontrols_pagers_gridviewpager_ascx' of type 'ASP.view_usercontrols_pagers_gridviewpager_ascx.']
System.Web.UI.ObjectStateFormatter.SerializeValue(SerializerBinaryWriter writer, Object value) +3395
System.Web.UI.ObjectStateFormatter.Serialize(Stream outputStream, Object stateGraph) +110
System.Web.UI.ObjectStateFormatter.Serialize(Object stateGraph) +57
System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Serialize(Object state) +4
System.Web.UI.Util.SerializeWithAssert(IStateFormatter formatter, Object stateGraph) +37
System.Web.UI.HiddenFieldPageStatePersister.Save() +79
System.Web.UI.Page.SavePageStateToPersistenceMedium(Object state) +105
System.Web.UI.Page.SaveAllState() +236
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1099


Version Information: Microsoft .NET Framework Version:2.0.50727.3082; ASP.NET Version:2.0.50727.4028

Best Answer

Why not just have your UserControl manage its own ViewState rather than trying to serialize itself?

public partial class GridViewPager : System.Web.UI.UserControl
{ 
    private int _startPage;

    public int StartPage 
    { 
        get { return _startPage; }
        set { _startPage = value; }
    }   

    protected override void LoadViewState(object savedState) 
    {
        object[] totalState = null;       
        if (savedState != null)
        {
           totalState = (object[])savedState;
           if (totalState.Length == 2)
           {
                base.LoadViewState(totalState[0]);
                // Load back your properties, etc. from ViewState
                if (totalState[1] != null)
                    startPage = int.Parse(totalState[1]);
            }
        }
    }

    protected override object SaveViewState()
    {
        object baseState = base.SaveViewState();
        object[] totalState = new object[2];
        // Save out your properties, etc. to ViewState.
        totalState[0] = baseState;
        totalState[1] = _startPage;
        return totalState;
    }
} 

This way when your UserControl is added to a page it will manage its own ViewSate.