我在使用GridView的时候,大部分情况下都是这么使用的:
有一个删除按钮或其他一些事件按钮,需要回发,执行这样的事件类似于这样
//删除会员
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
string keyID = GridView1.DataKeys[e.RowIndex].Value.ToString();
if (userData.DeleteUser(keyID))
{
this.BindUserList();
}
}
在这种情况下,我没法在在GridView的层次上禁用ViewState,如果我不禁用ViewState的话,20条记录ViewState大概在10000个字符左右。现在都流行压缩ViewState,虽然在性能上有所影响,总体来讲,也不失为一种好办法,压缩之后,字符数载1500个左右,少了将近10倍,压缩方法为:
Code
using System;
using System.Web.UI;
using System.IO;
using ICSharpCode.SharpZipLib.Zip.Compression;
namespace JianCaiWeb.Utils
{
/**//**/
/**//// <summary>
/// PageClass 的摘要说明。
/// </summary>
public class BasePage : System.Web.UI.Page
{
/**//**/
/**//// <summary>
/// 设定序列化后的字符串长度为多少后启用压缩
/// </summary>
private static Int32 LimitLength = 1096;
/**//**/
/**//// <summary>
/// 设定压缩比率,压缩比率越高性消耗也将增大
/// </summary>
private static Int32 ZipLevel = ICSharpCode.SharpZipLib.Zip.Compression.Deflater.BEST_COMPRESSION;
/**//**/
/**//// <summary>
/// 重写保存页的所有视图状态信息
/// </summary>
/// <param name="pViewState">要在其中存储视图状态信息的对象</param>
protected override void SavePageStateToPersistenceMedium(Object pViewState)
{
//实现一个用于将信息写入字符串的 TextWriter
StringWriter mWriter = new StringWriter();
//序列化 Web 窗体页的视图状态
LosFormatter mFormat = new LosFormatter();
//将有限对象序列化 (LOS) 格式化的对象转换为视图状态值
mFormat.Serialize(mWriter, pViewState);
//将序列化对象转成Base64字符串
String vStateStr = mWriter.ToString();
//设置是否启用了加密方式,默认情况下为不启用
Boolean mUseZip = false;
//判断序列化对象的字符串长度是否超出定义的长度界限
if (vStateStr.Length > LimitLength)
{
//对于长度超出阶线的进行加密,同时将状态设为加密方式
mUseZip = true;
Byte[] pBytes = Compress(vStateStr);
//将字节数组转换为Base64字符串
vStateStr = System.Convert.ToBase64String(pBytes);
}
//注册在页面储存ViewState状态的隐藏文本框,并将内容写入这个文本框
//RegisterHiddenField("__MSPVSTATE", vStateStr);
this.ClientScript.RegisterHiddenField("__MSPVSTATE", vStateStr);
//注册在页面储存是否启用压缩状态的文本框,并将启用状态写入这个文本框
//RegisterHiddenField("__MSPVSTATE_ZIP", mUseZip.ToString().ToLower());
this.ClientScript.RegisterHiddenField("__MSPVSTATE_ZIP", mUseZip.ToString().ToLower());
}
/**//**/
/**//// <summary>
/// 对字符串进行压缩
/// </summary>
/// <param name="pViewState">ViewState字符串</param>
/// <returns>返回流的字节数组</returns>
public static Byte[] Compress(String pViewState)
{
//将存储状态的Base64字串转换为字节数组
Byte[] pBytes = System.Convert.FromBase64String(pViewState);
//创建支持内存存储的流
MemoryStream mMemory = new MemoryStream();
Deflater mDeflater = new Deflater(ZipLevel);
ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream mStream = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream(mMemory, mDeflater, 131072);
mStream.Write(pBytes, 0, pBytes.Length);
mStream.Close();
return mMemory.ToArray();
}
/**//**/
/**//// <summary>
/// 重写将所有保存的视图状态信息加载到页面对象
/// </summary>
/// <returns>保存的视图状态</returns>
protected override Object LoadPageStateFromPersistenceMedium()
{
//使用Request方法获取序列化的ViewState字符串
String mViewState = this.Request.Form.Get("__MSPVSTATE");
//使和Request方法获取当前的ViewState是否启用了压缩
String mViewStateZip = this.Request.Form.Get("__MSPVSTATE_ZIP");
Byte[] pBytes;
if (mViewStateZip == "true")
{
pBytes = DeCompress(mViewState);
}
else
{
//将ViewState的Base64字符串转换成字节
pBytes = System.Convert.FromBase64String(mViewState);
}
//序列化 Web 窗体页的视图状态
LosFormatter mFormat = new LosFormatter();
//将指定的视图状态值转换为有限对象序列化 (LOS) 格式化的对象
return mFormat.Deserialize(System.Convert.ToBase64String(pBytes));
}
/**//**/
/**//// <summary>
/// 解压缩ViewState字符串
/// </summary>
/// <param name="pViewState">ViewState字符串</param>
/// <returns>返回流的字节数组</returns>
public static Byte[] DeCompress(String pViewState)
{
//将Base64字符串转换为字节数组
Byte[] pBytes = System.Convert.FromBase64String(pViewState);
ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream mStream = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(new MemoryStream(pBytes));
//创建支持内存存储的流
MemoryStream mMemory = new MemoryStream();
Int32 mSize;
Byte[] mWriteData = new Byte[4096];
while (true)
{
mSize = mStream.Read(mWriteData, 0, mWriteData.Length);
if (mSize > 0)
{
mMemory.Write(mWriteData, 0, mSize);
}
else
{
break;
}
}
mStream.Close();
return mMemory.ToArray();
}
}
}
压缩ViewState的方法挺好,但是却加重了服务器的负担。有没有更好的办法呢,既能减少ViewState,又不增加服务器端的负担,我这里到有一个,大家可以参考一下,
1 protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
2 {
3 if (e.Row.RowIndex != -1)
4 {
5 e.Row.EnableViewState = false;
6 //其他操作
7 }
8 }
关键的地方在第5行,加上这句话后,ViewState的大小为450个字符左右,比压缩的还要少3倍多,而且也没有增加服务器的负担,e.Row.EnableViewState=false,是禁止了一行的ViewState,有时候我们不能禁止一行的,但是可以禁止某些列,你可以这么写,e.Row.Cells[列号].EnableViewState=false。
这些都是在使用GridView的时候,发现的一些小的技巧,希望能对使用它的朋友有所帮助。