当页面发送到客户端浏览器后,用户对页面的操作本质上只会触发客户端的事件。比如,用户点击一个< input type=’button’/>的按钮,触发的Click事件其实只不过是客户端按钮的Click 事件,那么这个事件又是怎么“传染”到服务器端,触发服务器控件的事件的呢?
我们先来看看服务端控件生成的客户端代码,比如LinkButton 呈现的代码如下:
<a id="lbtnServer" href="javascript:__doPostBack('lbtnServer','')">OK</a>
在代码中看到了 “__doPostBack()”这个JavaScript函数的身影,那么它又是个什么东西呢?
在需要回传的页面中,asp.net的注册两个隐藏表单域和一段JavaScript脚本,这样来支持所有控件的回传:
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<script type="text/javascript">
//<![CDATA[
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>
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<script type="text/javascript">
//<![CDATA[
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>
结合前面的代码片段,可以看到需要触发服务器端事件的控件其实是调用了__doPostBack函数,分别把事件源和事件的参数赋值给表单的两个隐藏域:
__EVENTARGUMENT 和 __EVENTTARGET,然后提交表单到服务端。
在页面的生命周期里,有一个专门处理页面回传事件的阶段:RaisePostBackEvent,在这个阶段,页面会根据 __EVENTTARGET 的值找到事件的源控件,
然后根据改控件的 RaisePostBackEvent()方法,并把 __EVENTARGUMENT 作为参数传给控件。
此时,页面要求事件源控件具有 RaisePostBackEvent()方法,也就是说该控件必须实现IPostBackEventHandler接口。
参考:《道不远人:深入解析ASP.NET2.0控件开发》