注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

hurt0759的个人主页

人生常态--跋涉.人生暂态--歇息.

 
 
 

日志

 
 

ASP.NET页面如何引发PostBack事件  

2011-12-15 09:38:10|  分类: IT |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

这里面涉及到一些架构机制问题,比如说,对象间的信息通知,触发事件等.

用户在ASP.NET应用程序显示的页面上面点击一个Button、LinkButton、或者改变某个TextBox的Value时(启用AotuPostBack),就会导致页面提交,并且在服务器端引发对应的PostBack事件,大家可以想象客户端浏览器显示的是html,而html是不存在引发PostBack事件这一说的,这样就说明ASP.NET应用程序肯定提供一种方法,能够知道用户在客户端做了什么动作导致页面被提交的,然后服务器端根据这个信息引发相应的服务器端控件的PostBack事件,那么这篇文章,我们一起来讨论下ASP.NET应用程序是如何来引发PostBack事件.

首先我们通过最直接的方式来查看ASP.NET Page 根据什么信息来引发对应控件的PostBack事件的,我们知道 页面继承与 Page类,服务器端接受到一个页面请求时,服务器端会按预期的进行一系列的处理,这个就是Page 页面的生命周期,在这里我们就不讨论这个内容的,因为已经有很多文章介绍Page生命周期的内容的,这里我们只关注Page类型中RaisePostBackEvent方法里面的逻辑,我们通过Reflector查看 Page类型的RaisePostBackEvent方法.


 private void RaisePostBackEvent (NameValueCollection postData)
{
    if (this._registeredControlThatRequireRaiseEvent != null)
    {
        this.RaisePostBackEvent(this._registeredControlThatRequireRaiseEvent, null);
    }
    else
    {
        string str = postData["__EVENTTARGET"];
        bool flag = !string.IsNullOrEmpty(str);
        if (flag || (this.AutoPostBackControl != null))
        {
            Control control = null;
            if (flag)
            {
                control = this.FindControl(str);
            }
            if ((control != null) && (control.PostBackEventHandler != null))
            {
                string eventArgument = postData["__EVENTARGUMENT"];
                this.RaisePostBackEvent(control.PostBackEventHandler, eventArgument);
            }
        }
        else
        {
             this.Validate();
        }
    }
}


这段代码做这样几件事情,首先判断是否页面上有某个控件注册引发PostBack事件,通常通过Page.RegisterRequiresPostBack(Control control)方法来注册的,如果没有控件注册引发PostBack事件,那么就会查看回传页面的post数据中是否包含这样2个键值对,__EVENTTARGET 和 __EVENTARGUMENT,如果__EVENTTARGET键包含值,那么通过Page.FindControl找到控件的引用并查看该控件PostBackEventHandler是否为空,不为空那么就引发这个控件的PostBackEvent,这个就是ASP.NET如何引发页面回传事件的逻辑啦.

对于第一种方式在服务器端为某个控件注册需要引发回传事件,这通常是在我们开发的完全定制自定义控件中需要使用的(完全定制也就是不组合已有的服务器端控件),通过在自定义的控件中实现IPostBackEventHandler 和 IPostBackDataHandler 接口, IPostBackDataHandler接口需实现2个方法 bool LoadPostData(string postDataKey, NameValueCollection postCollection) 和 void RaisePostDataChangedEvent().我们需要在LoadPostData 方法中判断回发数据是否包含你想要的信息(页面提交会将form中的信息以key-value的形式提交到服务器,在这里我们只需要判断key-value集合中是否包含对应控件的Name属性即可),如果包含我们想要的信息,那么就说明是我们自定义的控件引发的回传,这样则可将这个控件注册为需要引发回传事件.

对于第二种方式,比如像LinkButton控件,其呈现时生成的Html代码不是<input type="submit"/>,因此他本身是不具备提交页面的功能,因此客户端必须通过JavaScript来实现页面提交,但是由于LinkButton呈现的html代码是<a>标签,页面提交时并不会将<a>标签key-value进行打包,所以页面提交后,服务器端无法找到到底是谁引发的页面回传,因此ASP.NET提供2个Hidden Input标签.

<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />

这2个东东相信大家经常看到,当你点击LinkButton时,客户端会通过JavaScript将被点击的LinkButton的Name和对应的参数存储在这2个hidden input中,然后提交页面,页面会将这2个hidden input 打包,以key-value的形式传回到服务器端,服务器端就可以通过  postData["__EVENTTARGET"] 来获取究竟是什么引发页面回传,进而找到其对应的服务端控件并触发其回传事件.

  评论这张
 
阅读(795)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017