ASP.NET事件回传机制在ASP.NET里面我们最喜欢做的事情是拖动一个Button然后双击,然后输入代码就可以了。这个称之为事件回传机制,属于软件开发的体系范畴,但并不属于Web开发的范畴,因为Web是基于TCP/IP协议的,但是TCP/IP协议确是一个无状态的协议,那么ASP.NET是如何引入事件回传的呢?
首先请新建一个网站,然后添加一个WebUserControl,命名为:EventModule。如下:
现在在该EventModule里面拖入一个一个Button和3个Label,如下:
然后双击该Button,输入如下代码:
this.Label1.Text = this.Button1.ID;
this.Label2.Text = this.Button1.ClientID;
this.Label3.Text = this.Button1.UniqueID;
将EventModule.ascx 拖入到Default.aspx里面,按F5测试,然后双击一下该Button,看看有什么情况。我这情况如下:
会不会觉得很疑惑呢?为什么这三个ID都不一样呢?那么事件模型机制跟这存在着什么联系呢?OK,我们右击该网页,选择查看源码,找到这一行:
<input type="submit" name="EventModule1$Button1" value="EventButton" id="EventModule1_Button1" />
哦,这个是什么?懂得ASP.NET的人会马上发现这个是该Button生成的HTML代码,搞ASP.NET开发的人可能会经常忽略掉这个HTML,因为这个并不是手工编写的,自己使用的挺方便的不是吗?如果这样想,那么我们这课也就没有什么意义了,刨根问底这是我最爱做的事情,如果您打算挖掘下去,那么请您继续,我保证这会让您对ASP.NET的根本会有深的了解,当这些根本的认识积累到一定程度后,就能编写出高性能的Web交互网站。
问题到这后我们该研究的是什么呢?大家可以想一想当客户端有人点击这个Button这后,服务器端能准确无误的响应相应的事件,那么想必在服务器端有一个找到该Button的方法,但是通过什么方法找到呢?
为了形成对比,比如为什么服务器知道是这个Button而不是另外一个Button触发了事件,我们在EventModule.ascx中拖入另一个Button,并双击它给它一个onclick事件,如下:
现在给上面的一个Button的事件代码里插入一个断点(注意,该断点只有在F5模式下才有用),如下:
F5测试,点击该Button,就会返回到VS2005调试模式下。“局部变量”窗口->this->base->Request下找到Form元素,如下展开:
注意上面的绿色高亮显示的地方,这里可以发现,即使我们放置了两个Button,但是通过TCP/IP协议返回到服务器端的却只有一个Button,并且该Key为那个Button在客户端对应的name值:EventModule1$Button1。这也是我为什么最开始让你们查看源代码的原因(注意:EventModuel1是EventModule.ascx在Default.aspx上自动创建的ID)。好了,真相应该比较清楚了,那么ASP.NET是如何通过EventModule1$Button1找到该Button的呢。首先我们可以做如下分析Default.aspx下有一个Child,名为EventModule1,EventModule1下有一个Button,名为Button1。于是“$"就成了我们查找子控件的标识符,由于在同一级页面里的所有子控件的ID必须不同,因而每个对象都对应一个UniqueID,也就是EventModule1$Button1,那么ASP.NET就能通过这种方式准确无误的找到我们对应的控件,并激活它所对应的OnClick事件。
呵呵,有点不知所云了吧,其实如果您对传统网站开发做过深入挖掘的话,这个是很好理解的,但是对于ASP.NET新手来说,这些可能是连自己想都没想过的事情,对底层的东西没有了解,很容易被ASP.NET的易用性引入一种误区。
那么LinkButton的事件又是如何实现的呢?LinkButton并不是属于form 中post方法中回传的数据,那么ASP.NET又是如何成功做到的呢?下面您将EventModule.ascx里面的控件全部删掉,并删掉EventModule.ascx.cs对应的代码,然后拖入一个LinkButton,然后双击它给它一个事件,按F5进入测试页面,右击打开源代码。会看到如下数据:<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<script type="text/javascript">
<!--
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
// -->
</script>
<a id="EventModule1_LinkButton1" href="javascript:__doPostBack('EventModule1$LinkButton1','')">LinkButton</a>
是不是看完后比较明白点什么呢?当该LinkButton被点击后,触发一个javascript函数__doPostBack('EventModule1$LinkButton1',''),前面一个参数就是其所对应的UniqueID,后面一个参数是__EventArgument,很少用到。函数被触发,然后将eventTarget和eventArgument的值传递给两个hidden input,由于hidden input会随着form表单的提交而传递到服务器端,于是在服务器端就得到了该LinkButton的UniqueID,然后再通过上述方法在网页生命周期前便很快地找到对应的控件,并触发事件。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1601365