服务器端ViewState(转)

ContractedBlock.gif ExpandedBlockStart.gif Code
一、首先谈一下服务器端 ViewState 的好处和弊端

1.服务器端 ViewState 的好处
1).避免了网络故障带来的 ViewState 传输错误问题 
2).避免了浏览器版本带来的 HiddenFiled 大小限制的问题
3).减少了传送至客户端的页面大小——因为 ViewState 存储在服务器

2.服务器端 ViewState 的弊端
1).占用大量的服务器端硬盘空间

二、服务器端 ViewState 的具体实现

建立一个继承自 System.Web.UI.Page 的   XViewStateFilesPage 类,代码如下:

using System.IO;
using System.Text;
using System.Web.UI;
namespace XanaduSoft.Web.UI
{
    
/**//// <summary>
    
/// 将 ViewState 存储在服务器磁盘上的 Page。
    
/// </summary>
    public class XViewStateFilesPage : Page 
    {
        
private const string m_strFilePathFormat = "~/PersistedViewState/{0}.vs.resource";
        
private const string m_strViewStateHiddenFieldName = "__ViewStateGuid";
        
private string m_strNewGuid = Guid.NewGuid().ToString();

        
private void WirteViewStateToFile(StringWriter SW)
        {
            
string strViewStateFilePath = MapPath(string.Format(m_strFilePathFormat,m_strNewGuid));
            
try
            {
                
using (StreamWriter objStreamWriter = File.CreateText(strViewStateFilePath))
                {
                    objStreamWriter.Write(SW.ToString());
                }
            }
            
catch (Exception exp)
            {
                
if (exp is DirectoryNotFoundException)
                {
                    Directory.CreateDirectory(strViewStateFilePath.Substring(
0,strViewStateFilePath.LastIndexOf(@"\"))); 
                    WirteViewStateToFile(SW);
                }
                
else
                {
                    
throw exp;
                }
            }
        }
        
        
/**//// <summary>
        
/// 重写 SavePageStateToPersistenceMedium 方法,保存 ViewState 到服务器磁盘
        
/// </summary>
        
/// <param name="viewState">object 的一个实例</param>
        protected override void SavePageStateToPersistenceMedium(object viewState) 
        {
            
// serialize the view state into a base-64 encoded string
            LosFormatter objLosFormatter = new LosFormatter();
            
using (StringWriter objStringWriter = new StringWriter())
            {
                
// save the view state to disk
                objLosFormatter.Serialize(objStringWriter,viewState);
                WirteViewStateToFile(objStringWriter);
            }
            
// saves the view state GUID to a hidden field
            Page.RegisterHiddenField(m_strViewStateHiddenFieldName,m_strNewGuid);
        }

        
/**//// <summary>
        
/// 重写 LoadPageStateFromPersistenceMedium 方法,从服务器磁盘读取 ViewState
        
/// </summary>
        
/// <returns></returns>
        protected override object LoadPageStateFromPersistenceMedium() 
        {
            
string strViewStateFilePath = MapPath(string.Format(m_strFilePathFormat,Request.Form[m_strViewStateHiddenFieldName]));
            
// deserialize the base-64 encoded string into a view state
            if (!File.Exists(strViewStateFilePath))
            {
                
throw new Exception("保存 Viewstate 的文件 \"" + strViewStateFilePath + "\" 不存在");
            }
            
else 
            {
                
// instantiates the formatter and opens the file
                LosFormatter objLosFormatter = new LosFormatter();
                StreamReader objStreamReader 
= File.OpenText(strViewStateFilePath);
                
string strViewState = objStreamReader.ReadToEnd();
                objStreamReader.Close();
                
return objLosFormatter.Deserialize(strViewState);
            }
        }
    }
}

三、“服务器端 ViewState”方案的实施

只要是项目中的所有页面都继承自 XanaduSoft.Web.UI.XViewStateFilesPage 即可。之后在项目的根目录下会自动创建一个 PersistedViewState 文件夹用于保存各个页面的 ViewState。

四、对于“占用大量的服务器端硬盘空间”的解决方案

对于服务器端 ViewState 占用过多服务器端硬盘空间的问题。我们可以有两种解决方法:

定期手动删除 
创建 HttpModules 用于定期删除 ViewState 文件,代码如下: 
using System;
using System.IO;
using System.Web;
using System.Threading;

namespace XanaduSoft.Web.HttpModules
{
    
public class XViewStateFilesCleanUpHttpModule : IHttpModule
    {
        
// this marks whether the clean-up code has exeucted or not
        private static bool m_bIsNeedRunning = true;
        
// this marks the path that contain the view state files
        private static string m_strCleanUpPath = HttpContext.Current.Server.MapPath("~/PersistedViewState/");
        
// this value is an equivelant of 2 days
        private static TimeSpan tsDaysToLeaveFiles = new TimeSpan(2,0,0,0);

        
private static void CleanUp()
        {
            
while (true)
            {
                
foreach (string strFilePath in Directory.GetFiles(XViewStateFilesCleanUpHttpModule.m_strCleanUpPath))
                {
                    FileInfo objFileInfo 
= new FileInfo(strFilePath);
                    
if (DateTime.Now.Subtract(objFileInfo.LastAccessTime) >= XViewStateFilesCleanUpHttpModule.tsDaysToLeaveFiles)
                    {
                        objFileInfo.Delete();
                    }
                }
                Thread.Sleep(XViewStateFilesCleanUpHttpModule.tsDaysToLeaveFiles);
            }
        }

        IHttpModule 必须实现的成员
#region IHttpModule 必须实现的成员
        
public void Init(HttpApplication context)
        {
            
if (XViewStateFilesCleanUpHttpModule.m_bIsNeedRunning)
            {
                
// creates a new background thread to run the clean-up code.
                Thread objThread = new Thread(new ThreadStart(CleanUp));
                
// starts the background thread
                objThread.Start();
                
// signals that the clean-up code has exeucted, reset m_dtLastExecuteTime
                XViewStateFilesCleanUpHttpModule.m_bIsNeedRunning = false;
            }
        }

        
public void Dispose()
        {
        }
        
#endregion
    }
}

编译命令行
csc 
/target:library /optimize /out:D:\XanaduSoft.Web.HttpModules.dll D:\XViewStateFilesCleanUpHttpModule.cs

应用方法(在Web.config中添加一下代码)
<httpModules>
<add name="ssafrs" type="XanaduSoft.Web.HttpModules.XViewStateFilesCleanUpHttpModule,XanaduSoft.Web.HttpModules" />
</httpModules>

转载于:https://www.cnblogs.com/madehua/archive/2009/03/24/1420490.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值