天天看點

C#強化系列文章一:ViewState使用兼談序列化

ViewState的使用比較簡單,一兩句話就可以了。

指派:ViewState[key] = value;

取值:value = ViewState[key];

最主要的作用就是可以在目前頁面儲存值,ASP.NET的頁面狀态維護就是使用ViewState來實作的,基本上每一個ASPX頁面都可以看到如下類似的html代碼:

C#強化系列文章一:ViewState使用兼談序列化

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkwNjc4NTIwMWRkyv4ncofW5vaWXdXRtXfXn3RYQR4=" />

C#強化系列文章一:ViewState使用兼談序列化

也就是說ViewState中的值實際上都是通過一個hidden來儲存的,hidden的name為__VIEWSTATE,那麼如果頁面上有另外一個控件的名稱也叫:__VIEWSTATE的話,會導緻頁面出錯。

其實在我們進行頁面開發或者進行自定義控件開發的時候,都可以使用ViewState,很友善。

ViewState是ASP.NET中特有的,相對于Session來說,它儲存的值隻能在目前頁面使用,并且儲存的隻能是已經序列化的類,比如.NET中的strings, integers, Booleans, arrays, ArrayList, hashtable,DataTable等。

那麼如何将自定義的類放入ViewState中呢,這個就涉及到如下所說的序列化的問題了:

序列化簡單來說就是把一個對象轉化成一種可以持久儲存的資料,當下次需要使用時再把之前儲存的資料反序列化成一個對象。

當然在.NET中提供了簡便的方法進行序列化的操作。

下面我以一個簡單的例子來說明

将自定義類Test儲存到viewstate中的按鈕事件代碼:

C#強化系列文章一:ViewState使用兼談序列化

    protected void Button1_Click(object sender, EventArgs e)

C#強化系列文章一:ViewState使用兼談序列化

    {

C#強化系列文章一:ViewState使用兼談序列化

        Test test = ViewState["VIEW_TEST"] as Test;

C#強化系列文章一:ViewState使用兼談序列化

        if (test == null)

C#強化系列文章一:ViewState使用兼談序列化

        {

C#強化系列文章一:ViewState使用兼談序列化

            test = new Test();

C#強化系列文章一:ViewState使用兼談序列化

        }

C#強化系列文章一:ViewState使用兼談序列化

        test[-1] = TextBox1.Text;

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

        ViewState["VIEW_TEST"] = test;

C#強化系列文章一:ViewState使用兼談序列化

    }

下面再看一下自定義類Test的實作:

C#強化系列文章一:ViewState使用兼談序列化

[SerializableAttribute]

C#強化系列文章一:ViewState使用兼談序列化

class Test

C#強化系列文章一:ViewState使用兼談序列化

{

C#強化系列文章一:ViewState使用兼談序列化

    private IList list;

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

    public Test()

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

        list = new ArrayList();

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

    public object this[int index]

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

        get

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

            if (index >= list.Count)

C#強化系列文章一:ViewState使用兼談序列化

            {

C#強化系列文章一:ViewState使用兼談序列化

                return null;

C#強化系列文章一:ViewState使用兼談序列化

            }

C#強化系列文章一:ViewState使用兼談序列化

            return list[index];

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

        set

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

            list.Add(value);

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

}

特别注意第一行的SerializableAttribute屬性,指定這個屬性後就代表此類是可以序列化的(具體序列化的過程都是由.NET内部進行的),那麼我們就可以把此類放入ViewState中了,如果沒有指定SerializableAttribute屬性的話,放入ViewState時就會報錯。

以上所示是序列化的第一種方式:基本序列化,也是比較簡單的一種,如果是複雜情況就要使用下面所說的第二種序列化的方式:自定義序列化

假設我們的Test類需要從DataTable繼承:

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

class Test : DataTable

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

        DataColumn col = new DataColumn();

C#強化系列文章一:ViewState使用兼談序列化

        col.DataType = typeof(string);

C#強化系列文章一:ViewState使用兼談序列化

        col.ColumnName = "name";

C#強化系列文章一:ViewState使用兼談序列化

        this.Columns.Add(col);

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

            if (index >= Rows.Count)

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

            return Rows[index]["name"];

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

            DataRow row = NewRow();

C#強化系列文章一:ViewState使用兼談序列化

            row["name"] = value;

C#強化系列文章一:ViewState使用兼談序列化

            Rows.Add(row);

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

那麼再把這個類放入ViewState的話就會報錯:此頁的狀态資訊無效,可能已損壞,主要是因為它的父類DataTable中的DataRow和DataColumn等是不可序列化的,我們就需要把這個類改造成如下形式:

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

class Test : DataTable, System.Runtime.Serialization.ISerializable

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

    public Test(SerializationInfo info, StreamingContext context)

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

        ArrayList list = info.GetValue("list", typeof(ArrayList)) as ArrayList;

C#強化系列文章一:ViewState使用兼談序列化

        foreach (string value in list)

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

    public void GetObjectData(SerializationInfo info, StreamingContext context)

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

        ArrayList list = new ArrayList();

C#強化系列文章一:ViewState使用兼談序列化

        foreach (DataRow row in this.Rows)

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

            list.Add(row["name"]);

C#強化系列文章一:ViewState使用兼談序列化

        } 

C#強化系列文章一:ViewState使用兼談序列化

        info.AddValue("list", list);

C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化
C#強化系列文章一:ViewState使用兼談序列化

1、實作ISerializable接口

2、實作GetObjectData方法,這個方法中就是把要序列化的對象放入info中,特别注意放入info中的對象本身必須是可以序列化的,如果放入一個DataRow對象,就會報錯:未标記為可序列化

3、實作public Test(SerializationInfo info, StreamingContext context) 構造函數,這個函數就是一個反序列化的操作,把info中的對象取出來

經過上面的改造之後,就可以把這個Test對象放入ViewState中了

   本文轉自永春部落格園部落格,原文連結:http://www.cnblogs.com/firstyi/archive/2007/11/20/965957.html,如需轉載請自行聯系原作者

繼續閱讀