程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> ViewState使用兼談序列化

ViewState使用兼談序列化

編輯:.NET實例教程
VIEwState的使用比較簡單,一兩句話就可以了。
賦值:VIEwState[key] = value;
取值:value = VIEwState[key];

最主要的作用就是可以在當前頁面保存值,ASP.Net的頁面狀態維護就是使用VIEwState來實現的,基本上每一個ASPX頁面都可以看到如下類似的Html代碼:

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkwNjc4NTIwMWRkyv4ncofW5vaWXdXRtXfXn3RYQR4=" />
也就是說VIEwState中的值實際上都是通過一個hidden來保存的,hidden的name為__VIEWSTATE,那麼如果頁面上有另外一個控件的名稱也叫:__VIEWSTATE的話,會導致頁面出錯。
其實在我們進行頁面開發或者進行自定義控件開發的時候,都可以使用VIEwState,很方便。

VIEwState是ASP.NET中特有的,相對於Session來說,它保存的值只能在當前頁面使用,並且保存的只能是已經序列化的類,比如.Net中的strings, integers, Booleans, arrays, ArrayList, hashtable等。
那麼如何將自定義的類放入VIEwState中呢,這個就涉及到如下所說的序列化的問題了:
序列化簡單來說就是把一個對象轉化成一種可以持久保存的數據,當下次需要使用時再把之前保存的數據反序列化成一個對象。
當然在.Net中提供了簡便的方法進行序列化的操作。
下面我以一個簡單的例子來說明
將自定義類Test保存到vIEwstate中的按鈕事件代碼:

    protected void Button1_Click(object sender, EventArgs e)
    {
        Test test = ViewState["VIEW_TEST"] as Test;
        if (test == null)
        {
            test = new Test();
        }
        test[-1] = TextBox1.Text;

        ViewState["VIEW_TEST"] = test;
    }
下面再看一下自定義類Test的實現:

[SerializableAttribute]
class Test
{
    private IList list;

    public Test()
    {
        list = new ArrayList();
    }

    public object this[int index]
    {
        get
        {
            if (index >= list.Count)
            {
                return null;
            }
            return list[index];
        }
        set
{
            list.Add(value);
        }

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

以上所示是序列化的第一種方式:基本序列化,也是比較簡單的一種,如果是復雜情況就要使用下面所說的第二種序列化的方式:自定義序列化
假設我們的Test類需要從DataTable繼承:

[SerializableAttribute]
class Test : DataTable
{
    public Test()
    {
        DataColumn col = new DataColumn();
        col.DataType = typeof(string);
        col.ColumnName = "name";
        this.Columns.Add(col);
    }

    public object this[int index]
    {
        get
{
            if (index >= Rows.Count)
            {
                return null;
            }
            return Rows[index]["name"];
        }
        set
        {
            DataRow row = NewRow();
            row["name"] = value;
            Rows.Add(row);
        }
    }
}那麼再把這個類放入VIEwState的話就會報錯:此頁的狀態信息無效,可能已損壞,主要是因為它的父類DataTable是不可序列化的,我們就需要把這個類改造成如下形式:

[SerializableAttribute]
class Test : DataTable, System.Runtime.Serialization.ISerializable

    public Test()
    {
        DataColumn col = new DataColumn();
        col.DataType = typeof(string);
        col.ColumnName = "name";
        this.Columns.Add(col);
    }

    public object this[int index]
    {
        get
        {
            if (index >= Rows.Count)
            {
                return null;
            }
            return Rows[index]["name"];
  }
        set
        {
            DataRow row = NewRow();
            row["name"] = value;
            Rows.Add(row);
        }
    }

    public Test(SerializationInfo info, StreamingContext context)
    {
        DataColumn col = new DataColumn();
        col.DataType = typeof(string);
        col.ColumnName = "name";
        this.Columns.Add(col);

        ArrayList list = info.GetValue("list", typeof(ArrayList)) as ArrayList;
        foreach (string value in list)
        {
            DataRow row = NewRow();
            row["name"] = value;
            Rows.Add(row);
        }
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        ArrayList list = new ArrayList();
        foreach (DataRow row in this.Rows)
        {
            list.Add(row["name"]);
        } 
        info.AddValue("list", list);
    }

}1、實現ISerializable接口
2、實現GetObjectData方法,這個方法中就是把要序列化的對象放入info中,特別注意放入info中的對象本身必須是可以序列化的,如果放入一個DataRow對象,就會報錯:未標記為可序列化
3、實現public Test(SerializationInfo info, StreamingContext context) 構造函數,這個函數就是一個反序列化的操作,把info中的對象取出來
經過上面的改造之後,就可以把這個Test對象放入VIEwState中了

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved