ASP.NET在禁用檢視狀態的情況下仍然使用ViewState對象

來源:互聯網
上載者:User
當開發人員禁用了頁面或控制項檢視狀態時。控制項開發人員一般在無奈情況下會使用控制項狀態,要重寫 LoadControlState,SaveControlState,還有一個OnInit方法,這樣固然完全可以實現控制項重要資料的控制項狀態資料儲存。但一般LoadControlState和SaveControlState方法都要開發人員自訂編程,比較麻煩,更適合對控制項中複雜的自訂類型資料進行對象序列化操作,比如一些簡單的類型如:string,int,bool,color,datetime,byte,arraylist等如果是控制項重要屬性的話,也都擠到LoadControlState 和 SaveControlState方法中,則會顯得比較囉唆。
想一下,如果整頁模式沒有禁用時該多好,可以以this.ViewState["Text"]的格式直接使用Control中的ViewState對象,非常方便。既然 ViewState對象不管禁用還是不禁用都在Control類中是存在的,那不用它豈不浪費。這一節主要內容就是如何?在禁用檢視狀態下仍然可以使用 ViewState對象。
該功能在主控制項ControlStateControl中已經實現了。回顧一下主控制項的程式碼片段:
///
/// 獲得本書更多內容,請看:
/// http://blog.csdn.net/ChengKing/archive/2008/08/18/2792440.aspx
///

public class ControlStateControl : WebControl
{
    //… …
    [Description("使用ViewState屬性來儲存資料此屬性")]
    public string Text_ViewState
    {
        get
        {
            String s = (String)ViewState["Text_ViewState"];
            return ((s == null) ? String.Empty : s);
        }

        set
        {
            ViewState["Text_ViewState"] = value;
        }
    }
    //… …
    protected override object SaveControlState()
    {
        Pair p = new Pair();
        p.First = base.SaveViewState();
        p.Second = ((IStateManager)FaceStyle).SaveViewState();
        //… …
        return p;
    }

    protected override void LoadControlState(object savedState)
    {
        if (savedState == null)
        {
            base.LoadViewState(null);
            return;
        }
        else
        {
            //… …
            base.LoadViewState(p.First);
            //… …
        }
    }
    //… …
}
在ControlStateControl中,屬性Text_ViewState仍然儲存在基類Control的ViewState對象中,且運行頁面中同時禁用了頁面和控制項檢視狀態,但該屬性仍然能夠正確地應用檢視狀態。
在檢視狀態啟用狀態下,在LoadViewState方法中會預設調用基類的base.LoadViewState方法,其中就包含對基類中ViewState對象進行對象序列化的代碼,如下:
protected virtual void LoadViewState(object savedState)
{
    if (savedState != null)
    {
        this.ViewState.LoadViewState(savedState);
        object obj2 = this.ViewState["Visible"];
        if (obj2 != null)
        {
            if (!((bool)obj2))
            {
                this.flags.Set(0x10);
            }
            else
            {
                this.flags.Clear(0x10);
            }
            this.flags.Set(0x20);
        }
    }
}
其中這句this.ViewState.LoadViewState(savedState)為關鍵語句,還記得ViewState屬性實際的類型為StateBag類,它是系統定義的類型檢視狀態實作類別(我們在6.2.3小節探討過)。
同樣在,SaveViewState方法中也有序列化儲存ViewState屬性對象的代碼,如下所示:
protected virtual object SaveViewState()
{
    if (this.flags[0x20])
    {
        this.ViewState["Visible"] = !this.flags[0x10];
    }
    if (this._viewState != null)
    {
        return this._viewState.SaveViewState();
    }
    return null;
}
關鍵語句為this._viewState.SaveViewState(),ViewState是對外屬性,其操作的變數就是StateBag類型的_viewState。
在檢視狀態被禁用的情況下,由於LoadViewState和SaveViewState不再被頁架構調用(預設情況下是base.SaveViewState和base.LoadViewState方法不會再被調用),所以ViewState屬性功能也就失效。
瞭解了ViewState對象的來龍去脈,現在就講解一下在ControlStateControl控制項中仍然可以使用ViewState的原因。在 LoadControlState和SaveControlState方法中分別調用base.LoadViewState和 base.SaveControlState,我們可以手動調用ViewState屬性對象的對象正還原序列化過程。歸根到底,也就是說開發人員所謂的禁用視圖實際上是禁止LoadViewState和SaveViewState兩個方法的執行,但理論上我們只要啟動控制項狀態,並把這兩個方法的邏輯放到 LoadControlState和SaveControlState中,仍然可以利用ViewState。
本節內容有些乖張,違反了 ASP.NET設計頁面狀態的規則。既然ASP.NET架構把視圖和控制項狀態已經分開了,建議在實際開發中分開處理,不要濫用。在 LoadControlState方法中盡量唯寫控制項狀態相關邏輯,在LoadViewState中唯寫檢視狀態相關邏輯,畢竟ControlState 是專門為儲存控制項必需的少量資料設計的。不過上面在ControlState中使用ViewState的確是非常方便的,在處理基本類型的屬性時能夠節省開發時間。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.