当前位置: 代码迷 >> ASP.NET >> 压缩ViewState后,在Convert.FromBase64String时偶尔会发生FormatException,该如何处理
  详细解决方案

压缩ViewState后,在Convert.FromBase64String时偶尔会发生FormatException,该如何处理

热度:1318   发布时间:2013-02-25 00:00:00.0
压缩ViewState后,在Convert.FromBase64String时偶尔会发生FormatException
压缩ViewState后,在Convert.FromBase64String时偶尔会发生FormatException,请教是什么原因?以下是BasePage中的相关代码
C# code
        private bool viewStateCompress = false;        protected bool ViewStateCompress        {            set { viewStateCompress = value; }            get { return viewStateCompress;}        }        protected override void SavePageStateToPersistenceMedium(object state)        {            if (!viewStateCompress)            {                 base.SavePageStateToPersistenceMedium(state);            }            else            {                Pair pair;                byte[] data;                byte[] compressedData;                string compressedStr;                object viewState = null, controlState = null;                LosFormatter formatter = new LosFormatter();                commonUtil.CompressHelper CH = commonUtil.CompressHelper.getInstance();                PageStatePersister persister = this.PageStatePersister;                if (state is Pair)                {                    pair = (Pair)state;                    viewState = pair.First;                    controlState = pair.Second;                }                else                {                    base.SavePageStateToPersistenceMedium(state);                    return;                }                StringWriter wViewState = new StringWriter();                StringWriter wControlState = new StringWriter();                formatter.Serialize(wViewState, viewState);                string viewStateStr = wViewState.ToString();                data = Convert.FromBase64String(viewStateStr);                compressedData = CH.Compress(data);                compressedStr = Convert.ToBase64String(compressedData);                persister.ViewState = compressedStr;                formatter.Serialize(wControlState, controlState);                string controlStateStr = wControlState.ToString();                data = Convert.FromBase64String(controlStateStr);                compressedData = CH.Compress(data);                compressedStr = Convert.ToBase64String(compressedData);                persister.ControlState = compressedStr;                persister.Save();            }        }        protected override object LoadPageStateFromPersistenceMedium()        {            if (!viewStateCompress)            {                 return base.LoadPageStateFromPersistenceMedium();            }            else            {                byte[] data;                byte[] uncompressedData;                string decompressedStr;                object viewState, controlState;                LosFormatter formatter = new LosFormatter();                commonUtil.CompressHelper CH = commonUtil.CompressHelper.getInstance();                PageStatePersister persister = this.PageStatePersister;                persister.Load();                string viewStateStr = persister.ViewState.ToString();                string controlStateStr = persister.ControlState.ToString();                try                {                    data = Convert.FromBase64String(viewStateStr);                    uncompressedData = CH.Decompress(data);                    decompressedStr = Convert.ToBase64String(uncompressedData);                    viewState = formatter.Deserialize(decompressedStr);                    data = Convert.FromBase64String(controlStateStr);                    uncompressedData = CH.Decompress(data);                    decompressedStr = Convert.ToBase64String(uncompressedData);                    controlState = formatter.Deserialize(decompressedStr);                }                catch(Exception exp)                {                     viewState = null;                    controlState = null;                }                return new Pair(viewState, controlState);            }        }


------解决方案--------------------------------------------------------
笑嘻嘻学习
------解决方案--------------------------------------------------------
学习
------解决方案--------------------------------------------------------
处理过程中没有必要设计base64编码。不论你写出什么二进制值,之后会被重新编码。而读入之前也会自动解码。因此你如果进行bas64编码,应该是额外多做了一道。

另外,压缩之前也没有必要base64编码。

------解决方案--------------------------------------------------------
学习
------解决方案--------------------------------------------------------
我只知道viewstate默认是Base64形式的数据
------解决方案--------------------------------------------------------
当Convert.FromBase64String方法的参数s的长度小于 4 或不是 4 的偶数倍时,将会抛出FormatException。
参考
http://www.cnblogs.com/heliguan/articles/1060481
------解决方案--------------------------------------------------------
不知道你的 commonUtil.CompressHelper 是什么,所以没法测试。我其实怀疑这样能够压缩多少。执行压缩,并且仍然是通过internet上无数的网卡、网线、路由器来回传递,这还是比较复杂的过程。我写了一个简单的过程,不压缩,用磁盘来代替网络,可以参考一下。这里也是输出字符串,但是并不做base64编码解码。
C# code
public class XVPage : Page{    static private DirectoryInfo _Dir;    private 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)        {            Pair pair = (Pair)state;            ps.ControlState = pair.First;            ps.ViewState = pair.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)    {        string stateStr = (string)Cache[stateID];        string file = Path.Combine(Dir.FullName, stateID);        if (stateStr == null)            stateStr = File.ReadAllText(file);        else            Cache.Remove(stateID);        return new ObjectStateFormatter().Deserialize(stateStr);    }    private string 序列化对象(object obj)    {        string value = new ObjectStateFormatter().Serialize(obj);        string stateID = (DateTime.Now.Ticks + (long)value.GetHashCode()).ToString(); //产生离散的id号码           File.WriteAllText(Path.Combine(Dir.FullName, stateID), value);        Cache.Insert(stateID, value);        return stateID;    }    protected override void OnUnload(EventArgs e)    {        base.OnUnload(e);        DateTime dt = DateTime.Now.AddMinutes(-20);        foreach (FileInfo fl in Dir.GetFiles())            if (fl.LastAccessTime < dt)                try                {                    fl.Delete();                }                catch                {                }    }}
------解决方案--------------------------------------------------------
你不会是仅仅为了在string与byte[]之间转换就动用了Base64编码解码功能了吧?在调用compressedData = CH.Compress(data);前后,都无需Base64解码和编码,直接把compressedData 从byte[]转换为string就可以了(无需编码)。
  相关解决方案