全美测评之:ASP.NET状态管理
考题:您在用asp.net开发时在服务端与客户端用到的存储状态信息的方式有几种?优缺点是什么?
相信做过asp.net项目的人对这块的了解应该很多,经常挂在嘴边或者是用到的有:session(server端),cookie(client端),viewstate(client端)等.
列表如下:
存储方法 | 信息量大小 | 作用域和保存时间 | 应用范围 | 保存位置 |
Application
|
任意大小
|
整个应用程序的生命期
|
整个应用程序/所有用户
|
服务器端
|
Cache
|
任意大小
|
可以根据需要设定
|
整个应用程序/所有用户
|
服务器端
|
Session
|
小量,简单数据
|
用户活动时间+一段延迟时间(一般为20分钟)
|
单个用户
|
服务器端
|
Cookie
|
小量,简单数据
|
可以根据需要设定
|
单个用户
|
客户端
|
Viewstate
|
小量,简单数据
|
一个Web页面的生命期
|
单个用户
|
客户端
|
隐藏域
|
小量,简单数据
|
一个Web页面的生命期
|
单个用户
|
客户端
|
查询字符串
|
小量,简单数据
|
直到下次页面跳转请求
|
单个用户
|
客户端
|
分别讲述这7种状态存储方式的利用场合、优缺点.
1、Application
利用场合:所有的请求都会需要的 一些共有资源,由最先的一个请求率先获取之后,拿出来共享,其他的请求就不用浪费资源进行再次获取。例如,一个 股市 Web 站点可能在一天中每 5 分钟从数据库获取大量的金融股票信息(也许是 40 MB 的数据),然后将这些信息缓存在应用程序状态中,这样 所有以后的查找请求都可以在应用程序状态中访问这些信息。其结果是极大地提高了每个请求的性能,因为传入的请求不需要跨进程、跨计算机或数据库的往返过程。
优点:易于实现,全局范围。
缺点:持久性,若保存数据的服务器端进程被强行关闭,那么数据就会丢失,所以利用Application一定要有保底的策略。
注意:因为Application中的数据被多个进程公用,所以若需要更新其中的值时,需要利用如下的语句,做到独占更新:
Application.Lock()
Application.Item("DataBase ") = NewDataBase
Application.UnLock()
以上的方式有没有缺点呢?有, 因为如果使用Application对象,一个需要考虑的问题是任何写操作都要在Application_OnStart事件(global.asax)中完成.尽管使用Application.Lock和Applicaiton.Unlock方法来避免写操作的同步,但是它串行化了对Application对象的请求,当网站访问量大的时候会产生严重的性能瓶颈.因此最好不要用此对象保存大的数据集合.
我们用vs2008的例子来讲解下:
2、Session
利用场合:单独的一个进程内部使用,存储单独会话的短期的、敏感的数据。
优 点 :易于实现持久性,可以应对IIS重启和辅助进程重启, 可在多进程中使用。
缺 点:耗用服务器端的内存。
这里我们要注意的一点是:当Session超时或被关闭时将自动释放保存的数据信息.由于用户停止使用应用程序后它仍然在内存中保持一段时间,因此使用Session对象使保存用户数据的方法效率很低.对于少量的数据,使用Session对象保存还是一个不错的选择。
2Session["key"]="value"
3//读取数据
4string UserName=Session["key"].ToString();
3、Cache
利用场合:整个应用程序中,需要经常用到的、更新周期不太频繁的数据。
优点:显著提高web应用程序的性能,把数据库记录缓存在内存中。
缺点:缓存过期的问题。一旦应用程序数据或者页面结果值发生的改变,那么在缓存有效期范围内,我们所获得的结果将是过期的、不准确的数据。典型的案例就是股票行情数据了吧。
解决方案:缓存依赖技术。
4、Cookie
利用场合:存储少量页面中经常改动的信息,如:为登陆过的网站保存登陆用户名,为用户输入提供方便.
优点:不使用服务器资源,实现简单,可配置到期时间。
缺点:4.1->大小受到限制,一般浏览器支持的最大的Cookie 容量为4096字节。
4.2->安全性:保存在客户端的信息可能会被恶意用户修改或者获取,所以不应该保存敏感信息。持久性:保存期限受到客户端的配置影响。
4.3->客户端用户可能会配置为拒绝Cookie。
Cookie 通常用于存取已知用户自定义内容的个性化情况。在大多数此类情况中,Cookie 是作为“标识”而不是“身份验证”,所以在 Cookie 中只存储用户名、账户名或唯一用户 ID(例如 GUID)并使用它来访问站点的用户个性化结构是足够的了。
2Response.Cookies["key"].Value="value";
3//读取信息
4string UserID=Response.Cookies["key"].Value;
5、ViewState
不得不说我们"可爱"的ViewState,现在多数开发团队在搭建基于web方向的应用程序时,估计用到最少的就是此君了,所有的Web服务器控件都使用ViewState在页面回发期间保存自己的状态信息,从而在页面上产生过多的"垃圾"代码,造成不必要的web应用程序资源浪费。
利用场合:在对同一页的多个请求间自动保留值,多用于客户端的一些事件。如:页面信息重置, 登陆出错次数统计,Grid列排序等。
优点:不利用服务器端资源,实现简单,相对高的安全性:因为经过哈希计算和压缩,并且针对 Unicode 实现进行编码。
缺点:因为ViewState存储在页面本身,所以无法存储较大的值。并且通过源文件可以看见其中的值 ,虽然经过哈希计算和压缩,但仍有被篡改的风险。
如果某个控件不需要在回发期间保存状态信息,最好关闭该对象的ViewState。通过给@Page指令添加“EnableViewState=false”属性可以禁止整个页面的ViewState。
2ViewState["key"]="value";
3//读取信息
4string NameID=ViewState["nameID"].ToString();
6、隐藏域->HiddenField:
利用场合:存储少量页面中经常改动的信息,多和客户端脚本一块使用,如:客户端经历一系列验证之后向服务器端回发,服务器端从客户端 HiddenField中获取值,进行处理。例如 :LeyserHomepage中,要删除一项产品,需要在客户端弹出确认Form,用户确认之后再 PostBack回服务器端进行数据库Delete操作,当用户确认要删除时,将当前要删除的产品ID存放到一个HiddenField中,然后执行Form(0).submit回发到服务器端,服务器端再从HiddenField获取产品ID值,进行数据库操作。
优点:不使用服务器资源 ,广泛支持,实现简单
缺点:安全性不高,因为它被包含在页面上进行发送,所以可以通过源文件看见他的内容。存储结构少,仅仅支持 string,integer,bool,array,arraylis t等简单的数据结构。并且在其上只存放简单的单值,若要存放多值,需要额外编 码。存储量少,因为它被存储在页面本身,所以 无法存储较大的值。而且大的数据量会受到防火墙和代理的阻止。 注意: 使用了HiddenField之 后,需要回发到服务器进行 处理,应该使用Http Post方法而不是Http Get方法(通过URL请求访问)
2Hidden.Value="0001";
3//获取信息
4string NameID=Hidden.Value;
7、查询字符串
利用场合:通过Response.Redirect方法实现客户端的重定向。(转发与重定向的区别是?)
优点:不同页面间信息传递性很强。
缺点:7.1->由于URL的长度有一定的限制,因此不能传递太大的信息。
7.2->安全性不是很好。