ASPNETViewState初探.docx
- 文档编号:15431333
- 上传时间:2023-07-04
- 格式:DOCX
- 页数:23
- 大小:66.48KB
ASPNETViewState初探.docx
《ASPNETViewState初探.docx》由会员分享,可在线阅读,更多相关《ASPNETViewState初探.docx(23页珍藏版)》请在冰点文库上搜索。
ASPNETViewState初探
ASP.NETViewState初探
ViewState到底是什么
与刚接触ASP.NET页面的开发人员交谈时,他们通常向我提出的第一个问题就是:
“那个ViewState到底是什么?
”他们的语气中流露出的那种感觉,就象我来到一家异国情调的餐馆,侍者端上一道我从未见过的菜肴时的那种感觉——既疑惑不解,又充满好奇。
但肯定有人认为它不错,否则就不会提供了。
所以,我会先尝一尝,或许会喜欢上它,尽管它看上去的确很古怪!
对于ViewState也是如此,但是如果适应了它的风格,您会发现在许多情况下,您将乐于在自己的ASP.NET应用程序中使用ViewState,因为它可以帮助您使用更少的代码完成更多的工作。
但是,有时也会对ViewState完全弃之不用。
下面我们就这两种情况分别进行阐述,不过,让我们先回答什么是ViewState这个问题。
答案:
ViewState用于维护页面的UI状态
ViewState到底是什么
与刚接触ASP.NET页面的开发人员交谈时,他们通常向我提出的第一个问题就是:
“那个ViewState到底是什么?
”他们的语气中流露出的那种感觉,就象我来到一家异国情调的餐馆,侍者端上一道我从未见过的菜肴时的那种感觉——既疑惑不解,又充满好奇。
但肯定有人认为它不错,否则就不会提供了。
所以,我会先尝一尝,或许会喜欢上它,尽管它看上去的确很古怪!
对于ViewState也是如此,但是如果适应了它的风格,您会发现在许多情况下,您将乐于在自己的ASP.NET应用程序中使用ViewState,因为它可以帮助您使用更少的代码完成更多的工作。
但是,有时也会对ViewState完全弃之不用。
下面我们就这两种情况分别进行阐述,不过,让我们先回答什么是ViewState这个问题。
答案:
ViewState用于维护页面的UI状态
Web是没有状态的,ASP.NET页面也没有状态,它们在到服务器的每个往返过程中被实例化、执行、呈现和处理。
作为Web开发人员,您可以使用众所周知的技术(如以会话状态将状态存储在服务器上,或将页面回传到自身)来添加状态。
下面我们以图1中的注册窗体为例进行论述。
图1:
恢复回传的窗体值
从上图中可以看出,我为便餐选择了一个无效的值。
此窗体与Web上的多数窗体一样友好,它在出现错误的字段旁边显示一条有用的错误消息和一个星号。
而且,窗体中还显示了我在其他文本框和下拉列表中输入的所有有效值。
这在某种程度上是可能的,因为HTML窗体元素会在HTTP标头中将其当前值从浏览器发送到服务器。
您可以使用ASP.NET跟踪来查看回传的窗体值,如图2所示。
图2:
HTTP窗体中回传的值(通过ASP.NET跟踪显示)
在ASP.NET之前,通过多次回传将值恢复到窗体字段中完全是页面开发人员的责任,他们将不得不从HTTP窗体中逐个拾取回传值,然后再将其推回字段中。
幸运的是,现在ASP.NET可以自动完成这项任务,从而为开发人员免除了一项令人厌烦的工作,同时也无需再为窗体编写大量的代码。
但这并不是ViewState。
ViewState(英文)是一种机制,ASP.NET使用这种机制来跟踪服务器控件状态值,否则这些值将不作为HTTP窗体的一部分而回传。
例如,由Label控件显示的文本默认情况下就保存在ViewState中。
作为开发人员,您可以绑定数据,或在首次加载该页面时仅对Label编程设置一次,在后续的回传中,该标签文本将自动从ViewState中重新填充。
因此,除了可以减少繁琐的工作和代码外,ViewState通常还可以减少数据库的往返次数。
ViewState的工作原理
ViewState确实没有什么神秘之处,它是由ASP.NET页面框架管理的一个隐藏的窗体字段。
当ASP.NET执行某个页面时,该页面上的ViewState值和所有控件将被收集并格式化成一个编码字符串,然后被分配给隐藏窗体字段的值属性(即
由于隐藏窗体字段是发送到客户端的页面的一部分,所以ViewState值被临时存储在客户端的浏览器中。
如果客户端选择将该页面回传给服务器,则ViewState字符串也将被回传。
在上面的图2中可以看到ViewState窗体字段及其回传的值。
回传后,ASP.NET页面框架将解析ViewState字符串,并为该页面和各个控件填充ViewState属性。
然后,控件再使用ViewState数据将自己重新恢复为以前的状态。
关于ViewState还有三个值得注意的小问题。
∙如果要使用ViewState,则在ASPX页面中必须有一个服务器端窗体标记(
窗体字段是必需的,这样包含ViewState信息的隐藏字段才能回传给服务器。
而且,该窗体还必须是服务器端的窗体,这样在服务器上执行该页面时,ASP.NET页面框架才能添加隐藏的字段。
∙页面本身将20字节左右的信息保存在ViewState中,用于在回传时将PostBack数据和ViewState值分发给正确的控件。
因此,即使该页面或应用程序禁用了ViewState,仍可以在ViewState中看到少量的剩余字节。
∙在页面不回传的情况下,可以通过省略服务器端的
'在ViewState中跟踪SortField属性
PropertySortField()AsString
Get
DimoAsObject=ViewState("SortField")
IfoIsNothingThen
ReturnString.Empty
EndIf
ReturnCStr(o)
EndGet
Set(ValueAsString)
IfValue=SortFieldThen
'与当前排序文件相同,切换排序方向
SortAscending=NotSortAscending
EndIf
ViewState("SortField")=Value
EndSet
EndProperty
'在ViewState中跟踪SortAscending属性
PropertySortAscending()AsBoolean
Get
DimoAsObject=ViewState("SortAscending")
IfoIsNothingThen
ReturnTrue
EndIf
ReturnCBool(o)
EndGet
Set(ValueAsBoolean)
ViewState("SortAscending")=Value
EndSet
EndProperty
PrivateSubPage_Load(senderAsObject,eAsEventArgs)HandlesMyBase.Load
IfNotPage.IsPostBackThen
BindGrid()
EndIf
EndSub
SubBindGrid()
'获取数据
DimdsAsNewDataSet()
ds.ReadXml(Server.MapPath("TestData.xml"))
DimdvAsNewDataView(ds.Tables(0))
'应用排序过滤器和方向
dv.Sort=SortField
IfNotSortAscendingThen
dv.Sort+="DESC"
EndIf
'绑定网格
DataGrid1.DataSource=dv
DataGrid1.DataBind()
EndSub
PrivateSubSortGrid(senderAsObject,eAsDataGridSortCommandEventArgs)
DataGrid1.CurrentPageIndex=0
SortField=e.SortExpression
BindGrid()
EndSub
[C#]
<%@PageLanguage="C#"%>
<%@ImportNamespace="System.Data"%>
在ViewState中存储非控件状态
此示例将一列静态数据的当前排序顺序存储在ViewState中。
单击列标题中的链接,可按该字段排序数据。
再次单击该链接,将按相反顺序排序。
datagridid="DataGrid1"runat="server"OnSortCommand="SortGrid" BorderStyle="None"BorderWidth="1px"BorderColor="#CCCCCC" BackColor="White"CellPadding="5"AllowSorting="True">
datagrid>
//在ViewState中跟踪SortField属性
stringSortField{
get{
objecto=ViewState["SortField"];
if(o==null){
returnString.Empty;
}
return(string)o;
}
set{
if(value==SortField){
//与当前排序文件相同,切换排序方向
SortAscending=!
SortAscending;
}
ViewState["SortField"]=value;
}
}
//在ViewState中跟踪SortAscending属性
boolSortAscending{
get{
objecto=ViewState["SortAscending"];
if(o==null){
returntrue;
}
return(bool)o;
}
set{
ViewState["SortAscending"]=value;
}
}
voidPage_Load(objectsender,EventArgse){
if(!
Page.IsPostBack){
BindGrid();
}
}
voidBindGrid(){
//获取数据
DataSetds=newDataSet();
ds.ReadXml(Server.MapPath("TestData.xml"));
DataViewdv=newDataView(ds.Tables[0]);
//应用排序过滤器和方向
dv.Sort=SortField;
if(!
SortAscending){
dv.Sort+="DESC";
}
//绑定网格
DataGrid1.DataSource=dv;
DataGrid1.DataBind();
}
voidSortGrid(objectsender,DataGridSortCommandEventArgse){
DataGrid1.CurrentPageIndex=0;
SortField=e.SortExpression;
BindGrid();
}
下面是上述两个代码段中引用的testdata.xml的代码:
xmlversion="1.0"standalone="yes"?
>
选择会话状态还是ViewState?
在某些情况下,将状态值保存在ViewState中并不是最佳选择,最常用的替代方法就是会话状态,它通常更适用于:
∙大量的数据。
由于ViewState增加了发送到浏览器的页面的大小(HTML有效负载),同时也增加了回传的窗体的大小,因此不适合存储大量数据。
∙未在UI中显示的安全数据。
尽管ViewState数据已被编码,并且可以选择对其进行加密,但始终不将数据发送到客户端才是最安全的。
因此,会话是更安全的选择。
(由于数据库需要额外的凭据进行验证,因此将数据存储在数据库中会更安全。
可以添加SSL以获得更安全的链接。
)但是,如果在UI中已经显示了该专用数据,那么您应该已经确认了链接的安全性。
在这种情况下,将同样的值放入ViewState不会降低安全性。
∙尚未序列化到ViewState中的对象,如DataSet。
ViewState序列化程序只为一小部分常用的对象类型进行了优化,如下所示。
其他可序列化的类型或许可以保留在ViewState中,但速度会变慢,并会生成一个非常大的ViewState。
使用ViewState获得最佳性能
使用ViewState时,每个对象都必须先序列化到ViewState中,然后再通过回传进行反序列化,因此使用ViewState并非是没有代价的。
但是,如果遵循某些简单的原则对ViewState的成本加以控制,则通常不会产生明显的性能影响。
∙在不需要时禁用ViewState。
下面的“减少使用ViewState”一节将详细介绍这一问题。
∙使用优化过的ViewState序列化程序。
上面列出的类型具有专门的序列化程序,这些程序运行速度很快,并已经过优化,可以生成很小的ViewState。
如果要序列化一个未在上面列出的类型,可以创建一个自定义TypeConverter来显著提高它的性能。
∙尽量减少使用对象,如果可能,尽量减少放入ViewState中的对象的数目。
例如,不要使用二维字符串数组(名称/值,其对象的数目与数组的长度一样多),而应使用两个字符串数组(只有两个对象)。
但是,在将两个已知类型存储在ViewState中之前,在这两者之间转换不会获得任何性能提高,因为这样做实际上相当于付出了两次转换的代价。
减少使用ViewState
默认情况下ViewState将被启用,并且是由每个控件(而非页面开发人员)来决定存储在ViewState中的内容。
有时,这一信息对应用程序并没有什么用处。
尽管也没什么害处,但却会明显增加发送到浏览器的页面的大小。
因此如果不需要使用ViewState,最好还是将它关闭,特别是当ViewState很大的时候。
可以基于每个控件、每个页面或每个应用程序来关闭ViewState。
在以下情况中将不再需要ViewState:
页面
∙页面不回传给自身。
控件
∙处理的不是控件的事件。
∙控件没有动态的或数据绑定的属性值(或对于每一个请求它们都设置在代码中)。
DataGrid控件是ViewState的一个重量级用户。
默认情况下,在网格中显示的所有数据也都存储在ViewState中,当需要一个复杂的操作(如复杂的搜索)来获取数据时,这是非常有用的。
但是,DataGrid的这种行为有时也使得ViewState成为累赘。
例如,这里有一个简单的页面就属于上述情况。
因为页面不回传给自身,所以它并不需要ViewState。
图3:
带有DataGrid1的简单页面LessViewState.aspx
<%@ImportNamespace="System.Data"%>
DataGridrunat="server"/> PrivateSubPage_Load(senderAsObject,eAsEventArgs) DimdsasNewDataSet() ds.ReadXml(Server.MapPath("TestData.xml")) DataGrid1.DataSource=ds DataGrid1.DataBind() EndSub 启用ViewState时,这个小网格会给该页面增加3000多字节
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ASPNETViewState 初探