zoukankan      html  css  js  c++  java
  • ASP.NET在禁用视图状态的情况下仍然使用ViewState对象【转】

    当开发人员禁用了页面或控件视图状态时。控件开发人员一般在无奈情况下会使用控件状态,要重写 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的确是非常方便的,在处理基本类型的属性时能够节省开发时间。
  • 相关阅读:
    LeetCode 109 Convert Sorted List to Binary Search Tree
    LeetCode 108 Convert Sorted Array to Binary Search Tree
    LeetCode 107. Binary Tree Level Order Traversal II
    LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal
    LeetCode 103 Binary Tree Zigzag Level Order Traversal
    LeetCode 102. Binary Tree Level Order Traversal
    LeetCode 104. Maximum Depth of Binary Tree
    接口和多态性
    C# 编码规范
  • 原文地址:https://www.cnblogs.com/myssh/p/1493184.html
Copyright © 2011-2022 走看看