摘要:學習筆記:Ch6實作PageStatePersister 來壓縮ViewState
1.壓縮方法
public class CompressHelp
{
//序列化工具,LosFormatter是頁面預設的序列器
private static LosFormatter _formatter = new LosFormatter();
/// <summary>
/// 解壓並反序列化狀態內容
/// </summary>
/// <param name="stateString">從用戶端取回的頁面狀態字串</param>
/// <returns>還原後的頁面狀態Pair物件</returns>
public static object Decompress(string stateString)
{
byte[] buffer = Convert.FromBase64String(stateString);
MemoryStream ms = new MemoryStream(buffer);//將內容放作MemoryStream
GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress);//解壓
MemoryStream msReader = new MemoryStream();
buffer = new byte[0x1000];// buffer = new byte[4096];
while (true)//將解壓內容讀入msReader
{
int read = zipStream.Read(buffer, 0, buffer.Length);
if (read <= 0)
break;
msReader.Write(buffer, 0, read);
}
zipStream.Close();
ms.Close();
msReader.Position = 0;//設定為最前面
buffer = msReader.ToArray();//取出內容
stateString = Convert.ToBase64String(buffer);//將byte變為字串
return _formatter.Deserialize(stateString);//反序列
}
/// <summary>
/// 序列化並壓縮狀態資料
/// </summary>
/// <param name="state">頁面狀態</param>
/// <returns>結果字串</returns>
public static string Compress(object state)
{
StringWriter writer = new StringWriter();
_formatter.Serialize(writer, state);
string stateString = writer.ToString();
byte[] buffer = Convert.FromBase64String(stateString);
//將壓縮內容寫入ms
MemoryStream ms = new MemoryStream();
GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress, true);
zipStream.Write(buffer, 0, buffer.Length);
zipStream.Close();
//將壓縮內容取出至buffer
buffer = new byte[ms.Length];
ms.Position = 0;
ms.Read(buffer, 0, buffer.Length);
ms.Close();
//將buffer轉成base64字串
stateString = Convert.ToBase64String(buffer);
return stateString;
}
}
{
//序列化工具,LosFormatter是頁面預設的序列器
private static LosFormatter _formatter = new LosFormatter();
/// <summary>
/// 解壓並反序列化狀態內容
/// </summary>
/// <param name="stateString">從用戶端取回的頁面狀態字串</param>
/// <returns>還原後的頁面狀態Pair物件</returns>
public static object Decompress(string stateString)
{
byte[] buffer = Convert.FromBase64String(stateString);
MemoryStream ms = new MemoryStream(buffer);//將內容放作MemoryStream
GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress);//解壓
MemoryStream msReader = new MemoryStream();
buffer = new byte[0x1000];// buffer = new byte[4096];
while (true)//將解壓內容讀入msReader
{
int read = zipStream.Read(buffer, 0, buffer.Length);
if (read <= 0)
break;
msReader.Write(buffer, 0, read);
}
zipStream.Close();
ms.Close();
msReader.Position = 0;//設定為最前面
buffer = msReader.ToArray();//取出內容
stateString = Convert.ToBase64String(buffer);//將byte變為字串
return _formatter.Deserialize(stateString);//反序列
}
/// <summary>
/// 序列化並壓縮狀態資料
/// </summary>
/// <param name="state">頁面狀態</param>
/// <returns>結果字串</returns>
public static string Compress(object state)
{
StringWriter writer = new StringWriter();
_formatter.Serialize(writer, state);
string stateString = writer.ToString();
byte[] buffer = Convert.FromBase64String(stateString);
//將壓縮內容寫入ms
MemoryStream ms = new MemoryStream();
GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress, true);
zipStream.Write(buffer, 0, buffer.Length);
zipStream.Close();
//將壓縮內容取出至buffer
buffer = new byte[ms.Length];
ms.Position = 0;
ms.Read(buffer, 0, buffer.Length);
ms.Close();
//將buffer轉成base64字串
stateString = Convert.ToBase64String(buffer);
return stateString;
}
}
2.實作PageStatePersister
/// <summary>
/// 實作PageStatePersister 來壓縮ViewState
/// </summary>
public class CompressPageStatePersister : PageStatePersister
{
//頁面狀態鍵值
private string PageStateKey = "____VIEWSTATE";
public CompressPageStatePersister(Page page)
: base(page)
{
}
public override void Load()
{
//取得頁面狀態鍵值
string postbackState = Page.Request.Form[PageStateKey];
if (string.IsNullOrEmpty(postbackState))
return;
//頁面狀態包括視圖狀態和控制項狀態兩部分
Pair statePair = (Pair)CompressHelp.Decompress(postbackState);
if(!Page.EnableViewState)
this.ViewState=null;
else
ViewState = statePair.First;//視圖狀態
this.ControlState = statePair.Second;//控制項狀態
}
public override void Save()
{
if (!Page.EnableViewState)
this.ViewState = null;
if (this.ViewState != null || this.ControlState != null)
{
Pair statePair = new Pair(ViewState, ControlState);//將頁面狀態及控制項狀態存到Pair
string stateString = CompressHelp.Compress(statePair);//壓縮物件並序列化成字串
Page.ClientScript.RegisterHiddenField(PageStateKey, stateString);//存在隱藏欄位
}
}
}
/// 實作PageStatePersister 來壓縮ViewState
/// </summary>
public class CompressPageStatePersister : PageStatePersister
{
//頁面狀態鍵值
private string PageStateKey = "____VIEWSTATE";
public CompressPageStatePersister(Page page)
: base(page)
{
}
public override void Load()
{
//取得頁面狀態鍵值
string postbackState = Page.Request.Form[PageStateKey];
if (string.IsNullOrEmpty(postbackState))
return;
//頁面狀態包括視圖狀態和控制項狀態兩部分
Pair statePair = (Pair)CompressHelp.Decompress(postbackState);
if(!Page.EnableViewState)
this.ViewState=null;
else
ViewState = statePair.First;//視圖狀態
this.ControlState = statePair.Second;//控制項狀態
}
public override void Save()
{
if (!Page.EnableViewState)
this.ViewState = null;
if (this.ViewState != null || this.ControlState != null)
{
Pair statePair = new Pair(ViewState, ControlState);//將頁面狀態及控制項狀態存到Pair
string stateString = CompressHelp.Compress(statePair);//壓縮物件並序列化成字串
Page.ClientScript.RegisterHiddenField(PageStateKey, stateString);//存在隱藏欄位
}
}
}
3.使用方式
public partial class CompressPageState : System.Web.UI.Page
{
protected override PageStatePersister PageStatePersister
{
get
{
return new CompressPageStatePersister(this);
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnShow_Click(object sender, EventArgs e)
{
this.lblMsg.Text = "";
for (int i = 0; i < 1000; i++)
{
this.lblMsg.Text += DateTime.Now.ToShortTimeString() + " OK:" + this.ViewStateControl1.FaceStyle.OK + "<br>";
}
}
}
{
protected override PageStatePersister PageStatePersister
{
get
{
return new CompressPageStatePersister(this);
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnShow_Click(object sender, EventArgs e)
{
this.lblMsg.Text = "";
for (int i = 0; i < 1000; i++)
{
this.lblMsg.Text += DateTime.Now.ToShortTimeString() + " OK:" + this.ViewStateControl1.FaceStyle.OK + "<br>";
}
}
}