在 ASP.NET 中,ViewState 因为在客户端的 HTML 里占据大量的空间,并随着页面的 PostBack 反复传递于网络中,一直为人垢病。但是实际上 ViewState 可以存储到数据库、缓存等任意地方,从而避免频繁将冗长的 base64 字符串发送到客户端。这样做不但可以显著提高性能(大幅度减少了网络传输的字节数),而且如果其中的内容也不会被轻易解密和破解。因此这个方法是很有用处的。
以下写了一个简单的例子,用缓存来作为 ViewState 存储目的地。至于缓存的 Key,文中给出的只是一个简单的写法,具体可以根据情况给出严密的方案。
代码大致演示如下:
以下写了一个简单的例子,用缓存来作为 ViewState 存储目的地。至于缓存的 Key,文中给出的只是一个简单的写法,具体可以根据情况给出严密的方案。
代码大致演示如下:
<%
@ Page language
=
"
c#
"
Codebehind
=
"
SaveViewStateToOther.aspx.cs
"
AutoEventWireup
=
"
false
"
Inherits
=
"
LinkedList.SaveViewStateToOther
"
%>
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< html >
< head >
< title > SaveViewStateToOther </ title >
< meta name ="GENERATOR" Content ="Microsoft Visual Studio .NET 7.1" >
< meta name ="CODE_LANGUAGE" Content ="C#" >
< meta name =vs_defaultClientScript content ="JavaScript" >
< meta name =vs_targetSchema content ="http://schemas.microsoft.com/intellisense/ie5" >
</ head >
< body MS_POSITIONING ="GridLayout" >
< form id ="Form1" method ="post" runat ="server" >< asp:DataGrid id =DataGrid1 style ="Z-INDEX: 101; LEFT: 104px; POSITION: absolute; TOP: 72px" runat ="server" BorderColor ="#3366CC" BorderStyle ="None" BorderWidth ="1px" BackColor ="White" CellPadding ="4" PageSize ="6" AllowPaging ="True" >
< selecteditemstyle font-bold ="True" forecolor ="#CCFF99" backcolor ="#009999" >
</ SelectedItemStyle >
< itemstyle forecolor ="#003399" backcolor ="White" >
</ ItemStyle >
< headerstyle font-bold ="True" forecolor ="#CCCCFF" backcolor ="#003399" >
</ HeaderStyle >
< footerstyle forecolor ="#003399" backcolor ="#99CCCC" >
</ FooterStyle >
< pagerstyle horizontalalign ="Left" forecolor ="#003399" backcolor ="#99CCCC" pagebuttoncount ="20" mode ="NumericPages" >
</ PagerStyle >
</ asp:DataGrid >
</ form >
</ body >
</ html >
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< html >
< head >
< title > SaveViewStateToOther </ title >
< meta name ="GENERATOR" Content ="Microsoft Visual Studio .NET 7.1" >
< meta name ="CODE_LANGUAGE" Content ="C#" >
< meta name =vs_defaultClientScript content ="JavaScript" >
< meta name =vs_targetSchema content ="http://schemas.microsoft.com/intellisense/ie5" >
</ head >
< body MS_POSITIONING ="GridLayout" >
< form id ="Form1" method ="post" runat ="server" >< asp:DataGrid id =DataGrid1 style ="Z-INDEX: 101; LEFT: 104px; POSITION: absolute; TOP: 72px" runat ="server" BorderColor ="#3366CC" BorderStyle ="None" BorderWidth ="1px" BackColor ="White" CellPadding ="4" PageSize ="6" AllowPaging ="True" >
< selecteditemstyle font-bold ="True" forecolor ="#CCFF99" backcolor ="#009999" >
</ SelectedItemStyle >
< itemstyle forecolor ="#003399" backcolor ="White" >
</ ItemStyle >
< headerstyle font-bold ="True" forecolor ="#CCCCFF" backcolor ="#003399" >
</ HeaderStyle >
< footerstyle forecolor ="#003399" backcolor ="#99CCCC" >
</ FooterStyle >
< pagerstyle horizontalalign ="Left" forecolor ="#003399" backcolor ="#99CCCC" pagebuttoncount ="20" mode ="NumericPages" >
</ PagerStyle >
</ asp:DataGrid >
</ form >
</ body >
</ html >
using
System;
using System.Data;
using System.IO;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace LinkedList
{
/// <summary>
/// SaveViewStateToOther 的摘要说明。
/// </summary>
public class SaveViewStateToOther : Page
{
protected DataGrid DataGrid1;
private void Page_Load( object sender, EventArgs e)
{
if ( ! IsPostBack)
Bind();
}
private void Bind()
{
DataTable table = new DataTable();
table.Columns.Add( " id " , typeof ( int ));
table.Columns.Add( " name " , typeof ( string ));
for ( int i = 0 ; i < 1000 ; i ++ )
{
DataRow row = table.NewRow();
row[ " id " ] = i;
row[ " name " ] = " student_ " + i.ToString();
table.Rows.Add(row);
}
DataGrid1.DataSource = table;
DataGrid1.DataBind();
}
#region Web 窗体设计器生成的代码
protected override void OnInit(EventArgs e)
{
InitializeComponent();
base .OnInit(e);
}
private void InitializeComponent()
{
this .DataGrid1.PageIndexChanged += new System.Web.UI.WebControls.DataGridPageChangedEventHandler( this .DataGrid1_PageIndexChanged);
this .Load += new System.EventHandler( this .Page_Load);
}
#endregion
protected override void SavePageStateToPersistenceMedium( object viewState)
{
LosFormatter format = new LosFormatter();
StringWriter writer = new StringWriter();
format.Serialize(writer, viewState);
string vsRaw = writer.ToString();
byte [] buffer = Convert.FromBase64String(vsRaw);
string vsText = Encoding.ASCII.GetString(buffer);
object v = Cache[PageKey];
if (v == null )
Cache.Insert(PageKey, vsText);
else
Cache[PageKey] = vsText;
}
public string PageKey
{
get { return Session.SessionID + " _page_SaveViewStateToOther_aspx " ; }
}
protected override object LoadPageStateFromPersistenceMedium()
{
object s = Cache[PageKey];
if (s != null )
{
string state = s.ToString();
byte [] buffer = Encoding.ASCII.GetBytes(state);
string vsRaw = Convert.ToBase64String(buffer);
LosFormatter formatter = new LosFormatter();
return formatter.Deserialize(vsRaw);
}
return null ;
}
private void DataGrid1_PageIndexChanged( object source, DataGridPageChangedEventArgs e)
{
DataGrid1.CurrentPageIndex = e.NewPageIndex;
Bind();
}
}
}
using System.Data;
using System.IO;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace LinkedList
{
/// <summary>
/// SaveViewStateToOther 的摘要说明。
/// </summary>
public class SaveViewStateToOther : Page
{
protected DataGrid DataGrid1;
private void Page_Load( object sender, EventArgs e)
{
if ( ! IsPostBack)
Bind();
}
private void Bind()
{
DataTable table = new DataTable();
table.Columns.Add( " id " , typeof ( int ));
table.Columns.Add( " name " , typeof ( string ));
for ( int i = 0 ; i < 1000 ; i ++ )
{
DataRow row = table.NewRow();
row[ " id " ] = i;
row[ " name " ] = " student_ " + i.ToString();
table.Rows.Add(row);
}
DataGrid1.DataSource = table;
DataGrid1.DataBind();
}
#region Web 窗体设计器生成的代码
protected override void OnInit(EventArgs e)
{
InitializeComponent();
base .OnInit(e);
}
private void InitializeComponent()
{
this .DataGrid1.PageIndexChanged += new System.Web.UI.WebControls.DataGridPageChangedEventHandler( this .DataGrid1_PageIndexChanged);
this .Load += new System.EventHandler( this .Page_Load);
}
#endregion
protected override void SavePageStateToPersistenceMedium( object viewState)
{
LosFormatter format = new LosFormatter();
StringWriter writer = new StringWriter();
format.Serialize(writer, viewState);
string vsRaw = writer.ToString();
byte [] buffer = Convert.FromBase64String(vsRaw);
string vsText = Encoding.ASCII.GetString(buffer);
object v = Cache[PageKey];
if (v == null )
Cache.Insert(PageKey, vsText);
else
Cache[PageKey] = vsText;
}
public string PageKey
{
get { return Session.SessionID + " _page_SaveViewStateToOther_aspx " ; }
}
protected override object LoadPageStateFromPersistenceMedium()
{
object s = Cache[PageKey];
if (s != null )
{
string state = s.ToString();
byte [] buffer = Encoding.ASCII.GetBytes(state);
string vsRaw = Convert.ToBase64String(buffer);
LosFormatter formatter = new LosFormatter();
return formatter.Deserialize(vsRaw);
}
return null ;
}
private void DataGrid1_PageIndexChanged( object source, DataGridPageChangedEventArgs e)
{
DataGrid1.CurrentPageIndex = e.NewPageIndex;
Bind();
}
}
}
对于实际的应用,如果要决定在整个程序中应用此方案,则使用一个通用的页面基类,在其中实现此机制比较合适。