服务器端ViewState的实现

在B/S项目开发中经常会遇到由于ViewState的数据量太大而产生Client与Server进行交互时的网络传输数据量过大从而导致效率低下的现象。为了解决这个问题可以采用服务器端ViewState的方法,将不影响页面显示的对象保存到服务器端的硬盘上,这种方法虽然没有使用Session的速度快,但是可以减少Client与Server的数据交互因此速度要远比发送到客户端高很多,与此同时由于数据保存到硬盘上还可以解决大数据量的问题。
可以使项目中的每个页面从一个基类去继承,在这个基类中实现如下的方法和属性。
ServerViewState的定义:
        private StateBag _serverViewState=null ;
        
protected StateBag ServerViewState
        
{
            
get
            
{
                
if(_serverViewState==null)
                
{
                    _serverViewState
=new StateBag(this.ViewStateIgnoresCase) ;
                }

                
return _serverViewState;
            }

        }

定义ServerViewState序列化后数据的保存路径:

        
private string ServerViewStatePath
        
{
            
get
            
{

                
string _strPath = Server.MapPath(Context.Request.ApplicationPath) + "/ServerViewState/"+Session.SessionID+"/";
                
if(!Directory.Exists(_strPath))
                
{
                    Directory.CreateDirectory(_strPath);
                }

                
string _fileName=this.GetType().BaseType.FullName+".ViewState";
                _strPath 
+= _fileName;
                _strPath 
= _strPath.Replace('\\','/');
                
return _strPath;
            }

        }

保存ServerViewState的方法:
protected override object SaveViewState()
        
{
            
if(_serverViewState!=null)
            
{
                
object serverViewState=SaveServerViewState();
                SavePageServerStateToPersistenceMedium(serverViewState);
            }

            
return base.SaveViewState ();
        }


        
private object GetServerViewStateObject(StateBag serverViewState)
        
{
            ArrayList keyList 
= null;
            ArrayList valueList 
= null;
            
if (serverViewState.Count != 0)
            
{
                IDictionaryEnumerator enumerator1 
= serverViewState.GetEnumerator();
                
while (enumerator1.MoveNext())
                
{
                    StateItem item1 
= (StateItem) enumerator1.Value;
                    
if (keyList == null)
                    
{
                        keyList 
= new ArrayList(5);
                        valueList 
= new ArrayList(5);
                    }

                    keyList.Add(enumerator1.Key);
                    valueList.Add(item1.Value);
                }

                
if (keyList != null)
                
{
                    
return new Pair(keyList, valueList);
                }

            }

            
return null;
        }


        
protected virtual object SaveServerViewState()
        
{
            
if (this._serverViewState != null)
            
{
                
return GetServerViewStateObject(this._serverViewState);
            }

            
return null;
        }

private void SavePageServerStateToPersistenceMedium(object serverViewState)
        
{
            StringBuilder _sb
=new StringBuilder() ;
            TextWriter _writer
=new StringWriter(_sb); 
            _formatter.Serialize(_writer,serverViewState) ;
            
string _strPath=ServerViewStatePath;
            
if(File.Exists(_strPath))
            
{
                File.Delete(_strPath);
            }

            FileStream fs
=new FileStream(_strPath,FileMode.OpenOrCreate,FileAccess.Write,FileShare.None) ;
            
using(StreamWriter sw=new StreamWriter(fs))
            
{
                sw.Write(_sb.ToString());
                sw.Close() ;
            }

            fs.Close() ;
        }

读取ServerViewState的方法:
protected override void LoadViewState(object savedState)
        
{
            
object viewState=LoadPageServerStateFromPersistenceMedium();
            
if(viewState!=null)
            
{
                
this._serverViewState=GetServerViewStateFromObject(viewState);
            }

            
this._serverViewState=null;
            
base.LoadViewState (savedState);
        }


        
private object LoadPageServerStateFromPersistenceMedium()
        
{
            
string _strPath=ServerViewStatePath;
            
if(!File.Exists(_strPath) )
            
{
                
return null;
            }

            FileStream fs
=new FileStream(_strPath,FileMode.Open,FileAccess.Read,FileShare.ReadWrite) ;
            
string _viewState=null;
            
using(StreamReader sr=new StreamReader(fs) )
            
{
                _viewState
=sr.ReadToEnd() ;
                sr.Close() ;
            }

            fs.Close() ;
            File.Delete(_strPath) ;
            
if(_viewState==null)
            
{
                
return null;
            }

            
return _formatter.Deserialize(_viewState) ;
        }


        
private StateBag GetServerViewStateFromObject(object viewState)
        
{
            Pair _pair
=viewState as Pair;
            
if(_pair!=null)
            
{
                StateBag state
=new StateBag(this.ViewStateIgnoresCase) ;
                ArrayList keyList
=_pair.First  as ArrayList;
                ArrayList valueList
=_pair.Second as ArrayList;
                
for (int i = 0; i < keyList.Count; i++)
                
{
                    state.Add((
string) keyList[i], valueList[i]);
                }

                
return state;
            }

            
return null;
        }

这样就可以在每个子页面中就可以直接调用ServerViewState,使用方法与ViewState完全相同,而不用顾虑后台的实现方式。

posted on 2005-07-19 11:47  Edward.Net  阅读(1620)  评论(4编辑  收藏  举报

导航