压缩ViewState后,在Convert.FromBase64String时偶尔会发生FormatException
压缩ViewState后,在Convert.FromBase64String时偶尔会发生FormatException,请教是什么原因?以下是BasePage中的相关代码
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); } }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就可以了(无需编码)。