将视图状态存入数据库(4)

前几天写了篇将视图状态存入数据库(3),这次发布的文件,修正了当控件状态比较小时,不保存在数据库中,而是保存在页面上。
using System;
using System.Web.UI;
using System.IO;
using ICSharpCode.SharpZipLib.Zip.Compression;
using System.Collections;
using JianCaiWeb.DbAccess;
using System.Text;
using System.Collections.Generic;
using System.Reflection;

namespace JianCaiWeb.Utils
{
    
/// <summary>
    
/// 读取控件状态,不是直接从数据库读取,而是先去状态池中查找,如果状态池中不存在,我们再访问数据库。
    
///
    
/// 状态池中的元素都是未序列化的,这样就避免了序列化和反序列化带来的性能问题。
    
/// </summary>

    public class DatabasePageStatePersister : PageStatePersister
    
{
        
private static DataAccess da;
        
private static int limitLength = 548;
        
//状态池
        private static List<DictionaryEntry> list = new List<DictionaryEntry>();
        
//状态池大小
        private static int viewStateCount = 1000;

        
public DatabasePageStatePersister(Page page)
            : 
base(page)
        
{
            da 
= DataAccessFactory.CreateDataAccess();
        }


        
//在 Page 对象初始化其控件层次结构时,加载保留的状态信息
        public override void Load()
        
{
            Pair statePair 
= null;
            
string clicentState = this.Page.Request["__VIEWSTATE"].ToString();

            
if (clicentState.Length != 0)
            
{
                
//获取页面的StateFormmatter
                IStateFormatter formatter = this.StateFormatter;
                
//序列化控件状态
                statePair = (Pair)formatter.Deserialize(clicentState);
            }

            
else
            
{
                
string stateID = base.Page.Request["__VIEWSTATE_KEY"].ToString();
                statePair 
= this.LoadViewState(stateID);
            }

            
this.ViewState = statePair.First;
            
this.ControlState = statePair.Second;
        }


        
// 在从内存中卸载 Page 对象时,对所保留的状态信息进行序列化。 
        public override void Save()
        
{
            
if (this.ViewState != null || this.ControlState != null)
            
{
                Guid guid 
= Guid.NewGuid();
                
string viewStateID = guid.ToString();
                
base.Page.ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
                Pair statePair 
= new Pair(ViewState, ControlState);

                
//获取页面的StateFormmatter
                IStateFormatter formatter = this.StateFormatter;
                
//序列化控件状态
                string serializedState = formatter.Serialize(statePair);
                
if (serializedState.Length < limitLength)
                
{
                    
//通过反射,找到页面实例的ClientState属性,将控件状态赋值给改属性
                    Type type = this.Page.GetType();
                    PropertyInfo property 
= type.GetProperty("ClientState", BindingFlags.Instance | BindingFlags.NonPublic);
                    property.SetValue(
this.Page, serializedState, null);
                }

                
else
                    
this.SaveViewState(viewStateID, statePair, serializedState);
            }

        }

        
//保存视图状态至状态池或数据库
        private void SaveViewState(string viewStateID, Pair statePair, string serializedState)
        
{
            DictionaryEntry newEntry 
= new DictionaryEntry();
            newEntry.Key 
= viewStateID;
            newEntry.Value 
= statePair;
            list.Add(newEntry);

            
string strSql = string.Format("insert into ViewState (viewStateID,ViewState) values ('{0}','{1}');", viewStateID, serializedState);
            
//将控件状态存入数据库
            da.ExecuteNonQuery(strSql);

            
//当状态池中的元素数量大于等于1000时,从开始位置移除多余的元素
            if (list.Count >= viewStateCount)
            
{
                list.RemoveRange(
0, list.Count - viewStateCount);
            }

        }

        
//从状态池或数据库中读取控件状态
        private Pair LoadViewState(string viewStateID)
        
{
            Pair statePair 
= null;
            
//遍历状态池,找到相应的控件状态
            foreach (DictionaryEntry entry in list)
            
{
                
if (entry.Key.ToString() == viewStateID)
                
{
                    statePair 
= (Pair)entry.Value;
                    
break;
                }

            }

            
//如果状态池中没有找到相应的控件状态,则从数据库中读取
            if (statePair == null)
            
{
                
string strSql = "select viewState from viewState where viewStateID = '" + viewStateID + "'";
                
string viewState = da.ExecuteScalar(strSql).ToString();
                
//获取页面的StateFormmatter
                IStateFormatter formatter = this.StateFormatter;
                
//序列化控件状态
                statePair = (Pair)formatter.Deserialize(viewState);
            }

            
return statePair;
        }

    }

}

具体怎么使用,参考将视图状态存入数据库(3)
posted @ 2008-05-08 15:30  王庆  阅读(451)  评论(2编辑  收藏  举报