视图状态入门指南






4.82/5 (216投票s)
本文是视图状态的分步指南,并包含详细信息。
目录
- 引言
- 什么是状态管理?
- 状态管理有哪些不同类型?
- 什么是视图状态?
- 视图状态的优点?
- 视图状态的缺点?
- 何时应使用视图状态?
- 何时应避免使用视图状态?
- 视图状态存储在哪里?
- 如何在视图状态中存储对象?
- 如何跟踪视图状态信息?
- 启用和禁用视图状态
- 如何使视图状态安全?
- 一些要点
引言
首先,我要感谢 Sean Ewington 先生的伟大创举,撰写了 Web 开发初学者指南 文章。我决定写一些关于状态管理方面的文章。Code Project 上有一些关于状态管理(主要是 Session、Caching、Cookies 等)的文章。尽管它们都非常棒,但我还是计划写一些关于状态管理的文章。我相信这肯定会对所有初学者有所帮助。我将内容组织得易于理解,不仅能帮助初学者,也能帮助高级用户。
在本文中,我将涵盖状态管理的基础知识和视图状态的详细信息。
什么是状态管理?
Web 是无状态
的。这意味着每次页面提交到服务器时,都会重新创建一个新的网页类实例。我们都知道HTTP
是一个无状态协议,它无法保留客户端的信息。例如,如果我们输入文本并点击提交按钮,文本在回发后不会显示,这完全是因为页面在往返过程中被重新创建了。
如上所述,页面在发送到客户端之前会被重新创建,并且每次请求都会发生这种情况。因此,维护网页和 Web 应用程序的信息状态是一个大问题。这就是状态管理
概念的由来。为了解决这个问题,ASP.NET 2.0 提供了一些功能,如View State、Cookies、Session、Application 对象
等来管理页面状态。
在选择合适的状态维护方式时,需要考虑一些选择标准,因为有很多种方式可以做到这一点。这些标准是:
- 你需要存储多少信息?
- 客户端是否接受持久性或内存中的 cookie?
- 您想将信息存储在客户端还是服务器端?
- 信息是否敏感?
- 您的应用程序有哪些性能和带宽标准?
- 您要定位的浏览器和设备有哪些功能?
- 您需要为每个用户存储信息吗?
- 您需要存储信息多长时间?
- 您是否有 Web 场(多台服务器)、Web 园(一台机器上多个进程)还是单个进程来服务应用程序?
因此,当您开始考虑状态管理时,应该考虑以上标准。基于这些标准,您可以选择最适合您 Web 应用程序的状态管理方法。
状态管理有哪些不同类型?
状态管理有两种不同的类型:
- 客户端状态管理
视图状态
隐藏字段
Cookie
控制状态
- 服务器端状态管理
Session
应用程序对象
缓存
数据库
客户端状态管理不使用任何服务器资源,它使用客户端选项存储信息。服务器端状态管理使用服务器资源存储数据。客户端和服务器端状态管理的选定应基于您的需求和已提供的选择标准。
什么是视图状态?
视图状态
是最重要且最有用的客户端状态管理机制之一。它可以在页面回发(发送和接收来自服务器的信息)
时存储页面值。ASP.NET 页面提供ViewState
属性作为内置结构,用于在同一页面的多次请求之间自动存储值。
示例
如果您想在视图状态中添加一个变量,
ViewState["Var"]=Count;
从视图状态检索信息
string Test=ViewState["TestVal"];
有时您可能需要类型转换视图状态值以进行检索。我在本文的最后提供了一个存储和检索对象到视图状态的示例。
视图状态的优点?
这是使用视图状态的主要优点:
- 易于实现
- 无需服务器资源
- 增强的安全功能,例如可以进行编码和压缩。
视图状态的缺点?
这是使用视图状态的主要缺点:
- 如果我们要存储大量数据,可能会导致性能开销,因为它只与页面相关。
- 它以散列格式(我稍后会讨论)存储在隐藏字段中,但仍很容易被捕获。
- 它在移动设备上没有支持。
何时应使用视图状态?
我已经描述了选择状态管理的标准。在选择视图状态来维护页面状态时,您应该记住以下几点。
- 数据量应较小,因为数据与页面控件绑定,因此对于大量数据可能会导致性能开销。
- 尽量避免在视图状态中存储安全数据。
何时应避免使用视图状态?
在以下情况下,您不需要控件的视图状态:
- 控件永远不会改变
- 控件在每次回发时都会重新填充
- 控件是输入控件,仅因用户操作而改变。
视图状态存储在哪里?
视图状态将页面控件的值存储为字符串,该字符串使用某些哈希和编码技术进行哈希和编码。它仅包含关于页面及其控件的信息。它不与服务器进行任何交互。它与页面一起保留在客户端浏览器中。视图状态使用隐藏
字段以编码格式存储其信息。
假设您编写了一个简单的代码来存储控件的值
ViewState["Value"] = MyControl.Text;
现在,运行您的应用程序,在浏览器中,右键单击
> 查看
源代码
,您将看到以下代码部分:
图:视图状态存储在隐藏字段中
现在,看看这个值。它看起来像一个加密的字符串,这是 Base64 编码的字符串,而不是加密字符串。因此,它可以轻松解码。Base64 使字符串适合 HTTP 传输,并使其稍微难以阅读。 了解更多关于 Base64 编码的信息。任何人都可以解码该字符串并读取原始值。所以要小心。视图状态存在安全漏洞
。
如何在视图状态中存储对象?
我们可以轻松地存储对象,就像存储字符串或整数类型的变量一样。但我们需要什么?我们需要将其转换为字节流。因为正如我之前所说,视图状态将信息存储在页面中的隐藏字段里。所以我们需要使用序列化
。如果我们要存储在视图状态中的对象不可序列化,我们将收到一条错误消息。
举个例子,
//Create a simple class and make it as Serializable
[Serializable]
public class student
{
public int Roll;
public string Name;
public void AddStudent(int intRoll,int strName)
{
this.Roll=intRoll;
this.Name=strName;
}
}
现在我们将尝试在视图状态中存储“Student
”类的对象。
//Store Student Class in View State
student _objStudent = new student();
_objStudent.AddStudent(2, "Abhijit");
ViewState["StudentObject"] = _objStudent;
//Retrieve Student information view state
student _objStudent;
_objStudent = (student)ViewState["StudentObject"];
如何跟踪视图状态信息?
如果您想跟踪您的视图状态信息,只需启用 Page 指令的“Trace
”选项即可。
现在运行您的 Web 应用程序,您可以在控件树
部分查看视图状态大小的详细信息以及控件 ID。不要担心“渲染大小字节
”,这只是渲染控件的大小。
启用和禁用视图状态
您可以为单个控件和页面级别启用和禁用视图状态。要关闭单个控件的视图状态,请将该控件的EnableViewState
属性设置为 false。例如:
TextBox1.EnableViewState =false;
要关闭整个页面的视图状态,我们需要将 Page 指令的EnableViewState
设置为 false,如下所示:
即使您禁用了整个页面的视图状态,您也会看到带有少量信息的隐藏视图状态标记。ASP.NET 始终至少存储页面的控件层次结构,即使视图状态被禁用。
要启用相同的功能,您只需使用相同的属性将其设置为 True。
例如,对于单个控件,我们可以通过以下方式启用视图状态:
TextBox1.EnableViewState =true;
对于页面级别:
如何使视图状态安全?
正如我之前讨论过的,视图状态信息以Base64 编码
字符串的形式存储在隐藏字段中,看起来像:
许多 ASP.NET 程序员认为这是一种加密格式
,但我再说一遍,这不是加密字符串。它可以轻易被破解。为了使您的视图状态安全,有两种选择:
-
首先,您可以通过使用
“哈希码”
来确保视图状态信息是防篡改的。您可以通过在页面指令中添加“EnableViewStateMAC=true
”来实现这一点。MAC 代表“消息认证码”
。
哈希码
是一个加密强的校验和
,由 ASP.NET 计算并添加到视图状态内容中,并存储在隐藏字段中。在下次回发时,将再次验证校验和数据,如果存在任何不匹配,则会拒绝回发。我们也可以在 web.config 文件中设置此属性。
-
第二个选项是在页面指令中设置
ViewStateEncryptionMode="Always"
,这将加密视图状态数据。您可以按以下方式添加:
ViewStateEncryptionMode
有三种不同的选项可供设置:
- Always
- 自动
- Never
Always
(始终)表示始终加密视图状态,Never
(从不)表示从不加密视图状态数据,Auto
(自动)表示,如果任何控件特别请求加密,则进行加密。对于自动模式,控件必须调用Page.RegisterRequiresViewStateEncryption()
方法来请求加密。
我们也可以在web.config中设置“EnableViewStateMAC
”和ViewStateEncryptionMode
”的设置。
注意:
尽量避免视图状态加密,除非有必要,因为它会导致性能问题。
一些要点
问题 | 答案 |
客户端还是服务器端? | 客户端 |
使用服务器资源? | 否 |
易于实现? | 是 |
导致性能问题? | 对于大量数据以及加密和解密的情况 |
支持加密解密? | 是 |
可以存储对象? | 是的,但您需要序列化该类。 |
Timeout | 否 |
关于视图状态就介绍到这里。希望您喜欢这篇文章,请不要忘记给我您宝贵的建议。如果有什么需要更新或更改的地方,请发布您的评论并给我建议。
参考
历史
写于 2008 年 11 月 29 日星期六
2008 年 12 月星期一进行小修正