简单的生活,简单的编程(Code Snippet Storage 2 进行中... ...)。
未经许可,请不要转载我的文章。
大家都知道Web应用程序的无状态,一个客户端的请求,在其请求完成后,服务器端都会删除这个请求的相关信息。有时我们需要Web请求完成后,还要继续保持信息,在传统的Web编程中最常用的有两种方式:Session、Cookies,但是这两种传统的方式,都有其弊端,Session会增加服务器的负担,Cookies则会依赖客户端,要求客户端必须支持Cookies,同时Cookies是存在客户端的计算机上,所以可能有安全问题。 在Asp.net里ms提出了一种新的状态保持,这就是ViewState,当然原来的Session和Cookies在Asp.net可以继续使用,那我们用一个Web的请求来说明一下ViewState的一个工作流程(只关心ViewState),即使不写asp.net服务器控件,但我想了解一下页面的请求和回传对写asp.net的程序还是很有好处的。
客户端向服务端请求一个新的aspx页面: 1、 服务器端会创建一个控件树,再创建页面上的所有控件,把控件加到控件树中。 2、 TrackViewState状态跟踪,检查控件的EnableViewState属性,对EnableViewState=ture的控件进行跟踪。 3、 触发页面OnLoad。 4、 预生成OnPreRender。 5、 检查控件的EnableViewState属性,对需要保存状态的调用SaveViewState[状态1]。 6、 Render生成。 7、 … …
从客户端回传一个aspx页面,页面被Post回服务端后。 A、 和上述1一样。 B、 和上述2一样。 C、 LoadViewState,加载控件提交前的状态[就是加载状态1]。 D、 LoadPostdata,从Post回来的表单中取出相应的数据,并把这些数据更新控件的状态[状态2]。 E、 和上述3一样。 F、 触发修改事件和回传事件。 G、 和上述4一样。 H、 保存状态SaveViewState[状态2]。 I、 Render。 J、 … …
上面就是ViewState的工作的一个流程,其实也就是aspx的生命周期,虽然我们在5和H对ViewState进行保存,在C进行了ViewState的装载,那又究竟是怎样保存和装载的呢?这就是ViewState的串行化和并行化的,在5和H对ViewState进行串行化,把这些状态序列化为一个字符串(如value="/wEPDwULLTE3NjgxMzM0MDIPZBYCZg9kFgICBg9kFgICAQ9kFhACAQ8PFgQeC05hdmlnYXRlVXJsBRdodHRwOi8vd3d3LmNuYmxvZ3MuY29tLx4EVGV4dAUJ5Y2a5a6i5ZutZGQCAw8PFgIfAAUdaHR0cDovL21hcHNlcnZlci5jbmJsb2dzLmNvbS9kZAIHDw8WBh4GVGFyZ2V0ZR8ABR1odHRwOi8vbWFwc2VydmVyLmNuYmxvZ3MuY29tLx8BBQltYXBzZXJ2ZXJkZAIJDw8WBB8ABRdodHRwOi8vd3d3LmNuYmxvZ3MuY29tLx4ISW1hZ2VVcmwFFn4vSW1hZ2VzL2FkbWlubG9nby5naWZkZAINDxYCHgdWaXNpYmxlZ2QCHQ9kFgICAQ9kFgQCAg8PFgIeC0N")发送到客户端,当页面再被Post回服务端的时候,在C又对这个字符串进行并行化,把它们反序列化为对象状态。aspx页面有串行化和并行化的过程,同时这两个过程的代价又是比较高昂的,所有我的原则是尽可能少的保存控件的ViewState。那什么样的对象可以被保存在ViewState中呢?原则上来讲,可以被序列化的对象都可以被保存在ViewState中,但是在asp.net中ViewState对Array、ArrayList和HashTable进行了优化。 在aspx页面的请求和回传过程中ViewState都是以明文形式传送,很容易被他人截取,对特别重要的信息可以考虑加密或者用Session等方式来保存,但这不是控件开发者的负责的,而应该是由页面开发者来完成。 最后:为什么我们需要回传的一个aspx页面都必须有一个运行Runat=”Server”的Form的,上述的D中我们看出,我们需要这个Form来回传控件的更新数据。同时我们也可以看到所有的ViewState的处理都是服务端进行的,与客户端没有任何的关系,所有不管你是ie的客户端还是firefox的客户端,都可以访问发布的asp.net站点。 如果在本文中发现有什么不妥的地方,请朋友们给与指点,小弟在此先谢过。
posted on 2006-06-08 00:33 mapserver 阅读(3207) 评论(18) 编辑 收藏 网摘 所属分类: Asp.net 服务器端控件
挺好... 回复 引用 查看
应该放在新手区 回复 引用 查看
lz的Asp.net控件系列搞快点写啊,我每隔几天就来看你的blog,结果都没有更新。 回复 引用
@世界杯来了 最近比较忙,都没有时间写,我会抓紧的。 回复 引用 查看
不错,刚好最近看ViewState的源码 回复 引用
您所列举的客户端向服务端请求一个新的aspx页面的过程,从严格的意义上来讲是有问题的。由于在asp.net 2.0中新增了控件状态,因此,在步骤C和H的前后会执行LoadControlState和SaveControlState。 当然了,如果要求不严格,您的说法,我认为也能够说明整个过程。 回复 引用 查看
问题1: 如果说“ViewState的处理都是服务端进行的”,那么 是不是可以理解为 Session 的另外一个名称。 因为他们都是在服务端进行。 问题2: 既然在服务端进行, 那为什么还要传输一串不小的数据 (414个字节 上文例子中)到客户端,然后再把这串数据再传回服务端? 问题3: 数据加密 不等于 数据不能被窃取!! 数据加密和不加密的区别是加密后的数据再被窃取后,被破解的难度比没有被加密的数据大。 回复 引用
@Luke Yang 问题3: 不回答,自己去考虑吧。 问题2、问题1: 在服务器端创建一个控件后,这个控件有很多的状态,asp.net把这些状态发到客户端,这些服务器端就可以把创建的这个控件及其状态从内存里删除(不考虑缓存),下次页面Post回来的时候,从这个字符串里恢复控件的原始状态,再加上Form传回来的数据,asp.net很容易就知道那些控件的状态有改变,从而去触发一些服务器端的事件,在这个过程中,服务器端并没有一直记录客户端的信息,而不像Session,Session会一直保留客户端的信息在服务器端,直到TimeOut,所以大量的Session会让服务器的压力过重。 回复 引用 查看
@POLARIS 谢谢你的评论,这篇文章主要是按1.1来写的,我会补上你说的那部分。 回复 引用 查看
公司的网站发布时遇到了viewstate的parse错误,补步分析是可能有人修改viewstate,用google找了下,说是可以通过程序修改viewstate,然后使用公司的邮件服务器去发垃圾邮件,不知道楼主有没有其它的建议。 回复 引用 查看
问题2、问题1: 在服务器端创建..... 楼主讲得不错,在Luke Yang提到这两个问题时我有同样的困惑。 回复 引用
viewstate 服务器端 串行化和并行化 回复 引用
问题~: 服务器是如何区分该页面是回传(postback)的还是第一次请求的~? 回复 引用
是不是查看viewstate是否为空~? 回复 引用
@冻结 if(!IsPostBack) {第一次加载} else {后面回传时候的代码} 用这个方法可以看是否回传 回复 引用 查看
@冻结 可以查看viewstate['属性']是否为空,但是不知道是否可以查看viewstate是否为空,具体的可以参考session的用法,和你同样等待楼主的答案 回复 引用 查看
<cc1:MyControl ID="MyControl 1" runat="server"> <cc1:CoulmnItem Field="" HeadText="zzz"> 内容 </cc1:CoulmnItem> </cc1:MyControl > 这是我的Control,通过集合编辑器增加CoulmnItem 时, 就构成了以下形式 <cc1:CoulmnItem Field="" HeadText="zzz" Content= "内容"> </cc1:CoulmnItem> 请问要怎么才能通过集合编辑器增加项时把内容放到<cc1:CoulmnItem></cc1:CoulmnItem>中呢? 回复 引用
写的不错 说得很清楚 MSN:wmj2212@126.com 请加我 回复 引用 查看
昵称: [登录] [注册]
主页:
邮箱:(仅博主可见)
验证码: 看不清,换一个
评论内容:
登录 注册
[使用Ctrl+Enter键快速提交评论]
Powered by: 博客园 Copyright © mapserver