• 将视图状态存入数据库(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)
  • 相关阅读:
    Activity的启动模式
    Activity的生命周期
    C之静态内存和动态内存
    C之指针的加法
    C之函数返回一个以上的值
    C之交换数据案例
    C之自定义类型
    C之枚举
    联合体
    C之结构体
  • 原文地址:https://www.cnblogs.com/fengfeng/p/1188513.html
Copyright © 2020-2023  润新知