压缩ViewState后,在Convert.FromBase64String时偶尔会发生FormatException

jamesfay 2008-12-16 06:42:28
压缩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);
}
}
...全文
433 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
jamesfay 2008-12-17
  • 打赏
  • 举报
回复
多谢sp1234,存放viewstate到文件的做法我也考虑过,可是由于我们服务器上不允许,所以就采用了压缩的办法,对于一些大页面非常有用。我原来的想法是因为viewstate是base64编码的,所以我就ConvertFromBase64->Compress->ConvertToBase64->SaveViewState。先前我采用的是RegisterHiddenField的做法,所以是手工Base64,如果直接存取persist对象可以自动转换base64的话那就太好了。我再debug一下试试看。
  • 打赏
  • 举报
回复
你不会是仅仅为了在string与byte[]之间转换就动用了Base64编码解码功能了吧?在调用compressedData = CH.Compress(data);前后,都无需Base64解码和编码,直接把compressedData 从byte[]转换为string就可以了(无需编码)。
  • 打赏
  • 举报
回复
不知道你的 commonUtil.CompressHelper 是什么,所以没法测试。我其实怀疑这样能够压缩多少。执行压缩,并且仍然是通过internet上无数的网卡、网线、路由器来回传递,这还是比较复杂的过程。我写了一个简单的过程,不压缩,用磁盘来代替网络,可以参考一下。这里也是输出字符串,但是并不做base64编码解码。
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
{
}
}
}
wuyq11 2008-12-16
  • 打赏
  • 举报
回复
当Convert.FromBase64String方法的参数s的长度小于 4 或不是 4 的偶数倍时,将会抛出FormatException。
参考
http://www.cnblogs.com/heliguan/articles/1060481.html
嘴哥臭鼬 2008-12-16
  • 打赏
  • 举报
回复
我只知道viewstate默认是Base64形式的数据
a3676212 2008-12-16
  • 打赏
  • 举报
回复
学习
  • 打赏
  • 举报
回复
处理过程中没有必要设计base64编码。不论你写出什么二进制值,之后会被重新编码。而读入之前也会自动解码。因此你如果进行bas64编码,应该是额外多做了一道。

另外,压缩之前也没有必要base64编码。
yby0260 2008-12-16
  • 打赏
  • 举报
回复
学习
jamesfay 2008-12-16
  • 打赏
  • 举报
回复
错误发生在LoadPageStateFromPersistenceMedium中的data = Convert.FromBase64String(viewStateStr); 是一个FormatException错误,很奇怪,我放进去的时候肯定是ToBase64了,为什么拿出来的东西会不对呢?

62,269

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧