• __doPostBack方法解析 __VIEWSTATE __EVENTTARGET __doPostBack __EVENTARGUMENT


    关于这个的另一篇博客:http://www.cnblogs.com/Silicon-Fado/archive/2009/04/21/1440437.html

    __VIEWSTATE:页面状态信息在客户端的存储(ViewState中存储的信息, EnableViewState="true"的控件状态信息).
    __EVENTTARGET:页面回传触发事件 页面回传触发事件:

    __doPostBack('Button2','')表示调用按钮Button2在后端的所对应的单击事件 控件回传触发事件:

    __doPostBack('TEST1$Button1','')表示调用TEST1控件中的Button1按钮的Click方法
    __EVENTARGUMENT:页面回传触发事件时所带的参数 如:__doPostBack('Button1','aa')在后端可以使用Request.Form["__EVENTARGUMENT"]来取得
    .net自动生成的一些客户端的代码 用来回传数据和自己带的一些脚本函数
    =====================================================================

    今天工作时遇到一个需要根据Gridview具体内容来判断是否弹出窗口,而Gridview中包含分页、排序等,它们并不能直接从查询字符串、或表单简单的分析出。这是因为存在__doPostBack方法,以及和其紧密关联的__ EVENTTARGET和__ EVENTARGUMENT。


    function __doPostBack(eventTarget, eventArgument)的eventTarget参数是GridView控件的名字,eventArgument参数是命令字。当如果是删除时,eventArgument参数是Delete开头;当如果是插入时,eventArgument参数是Insert开头;当如果是编辑时,eventArgument参数是Edit开头;当如果是选择时,eventArgument参数是Select开头。
     
    ============================================================
    客户端触发事件后调用__doPostBack方法,将表示触发的控件源的eventTarget 和事件参数eventArgument分别付给两个隐藏域__EVENTTARGET和__EVENTARGUMENT,然后提交Form,在服务端根据 __EVENTTARGET和__EVENTARGUMENT来判断是哪个控件的什么事件触发了。

    < script language="javascript">  
    
    function __doPostBack(eventTarget, eventArgument) 
    
    {
    
      var theform = document.WebForm2;
    
      theform.__EVENTTARGET.value = eventTarget;
    
      theform.__EVENTARGUMENT.value = eventArgument;
    
      theform.submit();
    
      }
    
    < /script>
    
    

    =================================================================Asp.net的postback机制我们知道Asp.net输出到客户端时都会被转化为HTML,页面Render到Client后,Client的HTML代码将包含如下代码:

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

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

    <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTA0NDQ2OTE5OWRk281L4eAk7iZT10hzg+BeOyoUWBQ=" />

    <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>

    其中隐藏字段_EVENTTARGET代表触发事件的控件。_EVENTARGUMENT代表事件的额外参数。为了页面能在PostBack后依然能读取服务器控件原有的状态数据,Asp.net中使用了ViewState技术,而ViewState技术本质上是用一个默认名称为__VIEWSTATE的Hidden类型表单域来保存和传递数据(这些数据是经过了序列化后Base64编码的字符串值)。控件的事件被Render后事件变成javascript:__doPostBack('Button1','')

    例如下面的样子

    <input type="button" name="Button1" value="Button1" onclick="javascript:__doPostBack('Button1','')" id="Button1" />

    ===============================================================================================

    这地方可看令一篇博文:http://www.cnblogs.com/Silicon-Fado/archive/2009/04/21/1440437.html

    只有两个Web Server Control 会自己触发页面的PostBack,其它的所有控件都是通过__doPostBack函数触发页面的PostBack页面解析时回将该类生成一个__doPostBack(eventTarget, eventArgument)方法。eventTarget是引起回送的控件的ID,eventArgument是回调参数(与控件相关的附加数据)。这两个参数分别由隐藏的两个表单域__ EVENTTARGET和__ EVENTARGUMENT保存。使用这两个隐藏的表单可以查找引起页面回送的控件ID和回送时的参数。

    当你触发__doPostBack事件时,遍历this.Request.Form.AllKeys,你查看到这两个隐藏的表单。

    由于最终呈现给浏览器的内容都是html内容,采用asp.net技术也不能例外.要实现webcontrol的postback机制.只能在原来的submit上做文章。

    我看到,asp.net现在页面上添加了两个hidden input,这两个input分别用来存放触发postback的control的ID和参数.这就是我们大部分人认识到的:

    __doPostBack(obj1,obj2)的第一个参数是控件ID,第二个参数是postback的参数.然后就可以在后台用Request.Form["__EVENTTARGET"]和Request.Form["__EVENTARGUMENT"]取得控件ID和参数.

    很简单就实现了看似很神奇,以为内部有什么高深的处理的过程!如此轻巧的实现了asp.net的postback机制,佩服佩服!只要我们看懂了上边的代码,对__doPostBack的使用就应该不是什么难事了.可以说__doPostBack就是这么简单的一回事.-_-||

    不过,另外要注意的就是asp.net的webcontrols中,Button和ImgButton是异类,它们不是利用__doPostBack来实现postback的.为什么这样,可能因为Button在html中本来就是有触发submit事件的功能吧.asp.net不过是要令原来html中一些不能触发submit的东西submit,才弄出了__doPostBack来实现.对于原来就能submit的Button,又何必多此一举呢.
    如上写法可以在后台找到Button.为什么这样? 不知道,呵呵. 在Button的提交过程中,Button会将Button本身的ID作为Request.Form的一个Key,它的Value是Button的Text属性值,回传给服务器.所以可以在后台循环Form.Keys取到所提交的Button,以执行相应的函数.ImgButton也差不多,不同就在于,它不是用ImageButton的ID作为Request.Form的Key,它是用ImageButton的ID加上.x和.y作为Key,在Request.Form添加两上键值对,这两个键值应该是对应ImageButton的图片大小的,了解了这个规律后,我们仍然可以通过一定的方式得到是否是由ImageButton引发的PostBack.

    如下面的我写的一个简单页面的例子,

    (1)页面中的下拉列表呈现在hyml中是这样的

    <select name="DropDownList2" onchange="javascript:setTimeout(&#39;__doPostBack(\&#39;DropDownList2\&#39;,\&#39;\&#39;)&#39;, 0)" id="DropDownList2">

    <option value="--请选择--">--请选择--</option>

    <option value="家用家具1">家用家具1</option>

    <option selected="selected" value="家用家具2">家用家具2</option>

    <option value="家用家具3">家用家具3</option>

    <option value="家用家具4">家用家具4</option>



    </select>

    可看到

    onchange="javascript:setTimeout(&#39;__doPostBack(\&#39;DropDownList2\&#39;,\&#39;\&#39;)&#39;, 0)" id="DropDownList2">

    此处下拉列表通过__doPostBack函数触发页面的PostBack页面解析时回将该类生成一个__doPostBack(eventTarget, eventArgument)方法。

    (2)对于按钮呢,则是这样的

    <input type="submit" name="Button1" value="确认" id="Button1" />

    按钮没有用到__doPostBack,原因是asp.net的webcontrols中,Button和ImgButton是异类,它们不是利用__doPostBack来实现postback的.为什么这样,可能因为Button在html中本来就是有触发submit事件的功能吧.asp.net不过是要令原来html中一些不能触发submit的东西submit,才弄出了__doPostBack来实现.对于原来就能submit的Button,又何必多此一举呢.

     ===================================================================================================

    当按钮被点击后,触发了__doPostBack事件,_doPostBack事件把表单提交给Server, Server端通过__EVENTTARGET这个hidden field的值找到对应的Server端的Control.接下来Server查看Control是否实现调用Page的RaisePostBackEvent,这个函数的定义如下:

    protected virtual void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)

    {

    sourceControl.RaisePostBackEvent(eventArgument);

    }

    函数调用本控件内的

    protected virtual void RaisePostBackEvent(string eventArgument)

    {

    base.ValidateEvent(this.UniqueID, eventArgument);

    iif (this.CausesValidation)

    {

    this.Page.Validate(this.ValidationGroup);

    }

    this.OnClick(EventArgs.Empty);

    this.OnCommand(new CommandEventArgs(this.CommandName, this.CommandArgument));

    }


     OnCommand实现了你定义的控件的函数。

  • 相关阅读:
    jdbc基础
    DAO模式(单表)
    window对象
    抽象类VS接口
    sql语句
    JS弹框计算
    HBML表单
    【mysql】:mysql性能优化总结
    【java】:多线程面试题
    spring multipart源码分析:
  • 原文地址:https://www.cnblogs.com/jinianjun/p/2343868.html
Copyright © 2020-2023  润新知