禁掉VIEWSTATE之后(三)

简介: 禁掉VIEWSTATE之后(一)      禁掉VIEWSTATE之后(二)      在前面两篇文章中,我们了解了VIEWSTATE的相关知识。在这里,我们可以再回头思考这个问题:什么时候可以禁用VIEWSTATE?如果感到这个问题太抽象,那么考虑下面这个问题:      仅就我们在第一节中实现的效果为例,如果禁用掉VIEWSTATE,如何实现启用VIEWSTATE时同样的效果? 对于已经习惯了asp.net机制的同学来说,这无疑将是一个痛苦的过程。

禁掉VIEWSTATE之后(一)     

禁掉VIEWSTATE之后(二)

 

     在前面两篇文章中,我们了解了VIEWSTATE的相关知识。在这里,我们可以再回头思考这个问题:什么时候可以禁用VIEWSTATE?如果感到这个问题太抽象,那么考虑下面这个问题:

     仅就我们在 第一节中实现的效果为例,如果禁用掉VIEWSTATE,如何实现启用VIEWSTATE时同样的效果?
对于已经习惯了asp.net机制的同学来说,这无疑将是一个痛苦的过程。更不用说在GridView等控件中,VIEWSTATE说起到的关键作用了(参考 烙馅饼喽同学的评论)。VIEWSTATE为我们做了太多的事情,我都有点想向这位默默无闻的英雄致敬了,呵呵!
     但是这里有一个无法回避的问题,VIEWSTATE增大了页面。似乎正应了那句古话:“鱼和熊掌,不可兼得!”
     所以可能会有同学提出以下的问题:
     1. 我的确需要存储GridView的控件状态,因为我不想每次都去数据库读取数据进行绑定运算(据说数据库的操作经常是系统的性能瓶颈);
     2. 但是我又不希望出现大量的VIEWSTATE;
     3. 而且我已经习惯了ASP.NET的处理方式,不希望对程序进行太多额外的改动。
     有办法么?
     呵呵,有的。从APS.NET2.O开始,微软为我们提供了!顾名思义,这个类可以将VIEWSTATE存储在Session中,而不是Hidden Input中。这可以用于大数量级的VIEWSTATE处理,它的实现也异常简单,只需要在页面后台(cs文件)中添加以下代码:
     protected   override  PageStatePersister PageStatePersister
    {
        
get
        {
            
return   new  SessionPageStatePersister( this );
        }
    }

     然后,我们可以比较使用了SessionPagePersister的页面源代码和未使用SessionPagePersister的页面源代码,可以看到,VIEWSTATE的大小差距。

img_405b18b4b6584ae338e0f6ecaf736533.gif 默认未使用SessionPagePersister
< input type = " hidden "  name = " __VIEWSTATE "  id = " __VIEWSTATE "  value = " /wEPDwUJMzY1MzQzMjM3D2QWAgIDD2QWAgINDzwrAA0CAA8WBB4LXyFEYXRhQm91bmRnHgtfIUl0ZW1Db3VudAKQTmQMFCsAARYGHgRUeXBlGSsBHgROYW1lBQRJdGVtHglEYXRhRmllbGQFASEWAmYPZBYWAgEPZBYCZg8PFgIeBFRleHQFATBkZAICD2QWAmYPDxYCHwUFATFkZAIDD2QWAmYPDxYCHwUFATJkZAIED2QWAmYPDxYCHwUFATNkZAIFD2QWAmYPDxYCHwUFATRkZAIGD2QWAmYPDxYCHwUFATVkZAIHD2QWAmYPDxYCHwUFATZkZAIID2QWAmYPDxYCHwUFATdkZAIJD2QWAmYPDxYCHwUFAThkZAIKD2QWAmYPDxYCHwUFATlkZAILDw8WAh4HVmlzaWJsZWhkZBgBBQxndndMYXJnZVNpemUPPCsACgEIAugHZLUwBYUzZxYn3Bl8dX4z95wP1H4o "   />


< input  type ="hidden"  name ="__VIEWSTATE"  id ="__VIEWSTATE"  value ="/wEPaA8FDzhjYzVhOWU5MGM2Nzk3YRgBBQxndndMYXJnZVNpemUPPCsACgEIAugHZGSWqXjymvf789VjkwDfpB6c6d+q"   />


     但是,这背后,究竟发生了什么?

     我们首先应该知道,在页面中,我们可以重写这两个方法(sp1234将VIEWSTATE存入服务器磁盘的方法就是这样实现的):
     LoadPageStateFromPersistanceMedium():
     SavePageStateFromPersistanceMedium():
     望文生义,我们就可以知道,以上这两个方法是用于加载(Load)和保存(Save)页面状态(PageState)到一个可持久化(Persistance)的介质(Medium)中的。如果用reflactor查看这两个方法,你会发现,他们其实只是封装了一个PageStatePersister实例的Load或Save方法。
     PageStatePersister其实是一个抽象类,它封装了处理VIEWSTATE的主要方法和属性(详细请参考MSDN)。
     它有两个子类:
     1. HiddenFieldPageStatePersister: 实现了将VIEWSTATE存放到 hidden input中(默认方式)
     2. SessionPageStatePersister: 实现了将VIEWSTATE存放到session中
     所以,当我们在页面中重写PageStatePersister属性之后,ASP.NET框架将使用SessionPageStatePersister来Load()和Save() VIEWSTAE。(这就是“面向对象”的强大之处!ASP.NET内部似乎还使用了Adapter设计模式,所以使得我们使用起来觉得异常的简单。)

     有人认为,这是对糟糕的VIEWSTATE状态机制的一种“补救”,但我更倾向于认为这是一种“扩展”——他仅仅是另一种选择而已,我们必须认识到:使用Session,也只是将负担转移到服务器内存而已。而Session的一个大问题是:它无法实时的清除,通常我们只是设定一个固定的“到期时间”,这无疑是比较缺乏灵活性的(过期时间设得过长,会造成内存资源的浪费;而过期时间设得过短,将会导致信息的丢失)。
相关文章
|
存储 .NET
突然发现 ViewState,Linq 水火不容
刚才在写一个小东西,突然发现一个问题。很奇怪,希望大家能帮忙解决一下   我用WebForm+Linq 做一个小网站,在读取数据的时候,我想将Linq 读取出来的泛型集合缓存起来。大家自然想到asp.net中的几个内置对象来存储。
789 0
|
C# .NET 开发框架

热门文章

最新文章