日期:2014-05-20 浏览次数:21274 次
using System;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Web.UI;
public class XVPage : Page
{
    static private DirectoryInfo _Dir;
    private static DirectoryInfo Dir
    {
        get
        {
            if (_Dir == null)
            {
                _Dir = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data"));
                if (!_Dir.Exists)
                    _Dir.Create();
                _Dir = new DirectoryInfo(Path.Combine(_Dir.FullName, "ViewState"));
                if (!_Dir.Exists)
                    _Dir.Create();
            }
            return _Dir;
        }
    }
    protected override object LoadPageStateFromPersistenceMedium()
    {
        PageStatePersister ps = this.PageStatePersister;
        ps.Load();
        if (ps.ControlState != null)
            ps.ControlState = 反序列化对象((string)ps.ControlState);
        if (ps.ViewState != null)
            ps.ViewState = 反序列化对象((string)ps.ViewState);
        return new Pair(ps.ControlState, ps.ViewState);
    }
    protected override void SavePageStateToPersistenceMedium(object state)
    {
        PageStatePersister ps = this.PageStatePersister;
        if (state is Pair)
        {
            ps.ControlState = ((Pair)state).First;
            ps.ViewState = ((Pair)state).Second;
        }
        else
            ps.ViewState = state;
        if (ps.ControlState != null)
            ps.ControlState = 序列化对象(ps.ControlState);
        if (ps.ViewState != null)
            ps.ViewState = 序列化对象(ps.ViewState);
        ps.Save();
    }
    private object 反序列化对象(string stateID)
    {
        if (stateID == null)
            return null;
        object state = Cache[stateID];
        string fname = Path.Combine(Dir.FullName, stateID);
        if (state == null)
            using (var stream = File.OpenRead(fname))
                state = new BinaryFormatter().Deserialize(stream);
        this.Page.SaveStateComplete += (s, e) =>    //当发生异常时,此方法不会执行,因此可以保证不会误删ViewState文件
        {
            Cache.Remove(stateID);
            File.Delete(fname);     //这个方法恰好可以禁止浏览器端的“刷新”。
        };
        return state;
    }
    static long seed1 = DateTime.Now.Ticks;
    static ulong seed2 = 0;
    private string 序列化对象(object obj)
    {
        string stateID = seed1.ToString() + "_" + (seed2++).ToString();
        Cache.Insert(stateID, obj, null, DateTime.Now.AddMinutes(5), TimeSpan.Zero);
        var stream = new MemoryStream();
        new BinaryFormatter().Serialize(stream, obj);
        File.WriteAllBytes(Path.Combine(Dir.FullName, stateID), stream.ToArray());
        return stateID;
    }
    static XVPage()
    {
        var et = DateTime.Now.AddMinutes(-30);
        Dir.GetFiles()
            .Where(f => f.LastAccessTime < et)
            .ToList()
            .ForEach(f =>
            {
                try
                {
                    f.Delete();
                }
                catch { }
            });
    }
}