理解 __doPostBack--1

来源:互联网 发布:网络用语辣鸡什么意思 编辑:程序博客网 时间:2024/06/06 03:55

__doPostBack作为在asp.net中一个很重要的部分,有必要深入了解一下__doPostBack的来龙去脉的.其实,__doPostBack是一个很简单的JS function.代码如下:

 

__doPostBack
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}

 

因为最终呈现给浏览器的内容都是html内容,采用asp.net技术也不能例外.要实现webcontrolpostback机制.只能在原来的submit上做文章.ms呈现给我们的,就是这种精巧的思维!

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

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

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

不过,另外要注意的就是asp.netwebcontrols,ButtonImgButton是异类,它们不是利用__doPostBack来实现postback.为什么这样,可能因为Buttonhtml中本来就是有触发submit事件的功能吧.asp.net不过是要令原来html中一些不能触发submit的东西submit,才弄出了__doPostBack来实现.对于原来就能submitButton,又何必多此一举呢.(仅个人理解,未经验证!)

所以如果是Buttonpostback,在后台是不能用Request.Form["__EVENTTARGET"]Request.Form["__EVENTARGUMENT"]取得控件ID和参数的.那么,怎么取呢?看代码:

 

Button
foreach (string str in Request.Form)
{
Control c = Page.FindControl(str);
if (c is Button)
{
control = c;
break;
}
}

 

如上写法可以在后台找到Button.为什么这样? 不知道,呵呵. Button的提交过程中,Button会将Button本身的ID作为Request.Form的一个Key,它的ValueButtonText属性值,回传给服务器.所以可以在后台循环Form.Keys取到所提交的Button,以执行相应的函数.ImgButton也差不多,不同就在于,它不是用ImageButtonID作为Request.FormKey,它是用ImageButtonID加上.x.y作为Key,在Request.Form添加两上键值对,这两个键值应该是对应ImageButton的图片大小的,了解了这个规律后,我们仍然可以通过一定的方式得到是否是由ImageButton引发的PostBack.

了解Postback机制对我们理解asp.net的事件触发过程有很大的帮助,好好利用__doPostBack更能灵活的使客户端和服务器端进行交互,获得更好的客户体验.

 

.NET中,所有的服务器控件提交到服务器的时候,都会调用__doPostBack这个函数,所以灵活运用这个函数对于我们的帮助还是很大的。  
   
 
比如,在我们写程序的时候经常会需要动态的生成一些控件,最简单的方法就是通过一个字符串,比如string   strButton     =     <input   type   =”button”   ID=”button1”>,然后输出到页面,但是如果我们需要这个控件来执行一些服务器的功能,就比较困难了。这里我们就可以用过借用__doPostBack这个函数来完成。接下来我觉个例子来说明一下具体如何调用。
 
   
 
既然要在服务器端运行那么,我们可以声明一个不可见的LinkButton控件,那通常,我们希望一个控件不可见,通常都是把visible属性设为false。但是在这里我们把LinkButtonText属性设置为空,来是这个LinkButton不可见(为什么要这么设置,而不是直接设置visible属性,我会在下面说明),接下来我们可以在LinkButton里面写一些服务器端的代码。然后就是如何通过我们动态生成的客户端控件来调用LinkButton里面的功能,我们可以通过一个JavaScript函数来实现
 
   
  function   ExcuteOnServer()  
  {  
      //
第一个参数是你希望提交到服务器的控件的ID号,第二个参数是事件参数
 
        __doPostBack('LinkButtonID','');  
  }  
   
 
接下去我们只需要在动态生成的这个Button控件的onclick事件中写上onclick=”JavaScript:ExcuteOnServer();“,这样当我们点击这个动态生成的客户端控件的时候,他便会执行LinkButton中的代码。
 
   
 
这样便实现了动态生成的客户端控件提交到服务器端的功能。
 
   
  最后要说一下的就是为什么希望LinkButton控件不可见的时候,不是通过visible属性来完成的。因为当我们把visible属性设置为false的时候,浏览器在解析的时候,根本不会把这个控件放在页面上,也就是说这个控件是不存在的,所以我们在调用__doPostBack函数的时候,便会找不到控件。

 

这里介绍一个常用的函数_doPostBack,这个函数如果如果是ASP.Net render出来的页面就是自动产生这个函数,比如有带autopostback属性的控件,且其属性为true的页面,带编辑列的datagrid页面。
__doPostBack
是通过__EVENTTARGET,__EVENTARGUMENT两个隐藏控件向服务端发送控制信息的,__EVENTTARGET为要调用控件的名 称,如果要调用的控件是子控件,用''$'':'分割父控件:子控件,__EVENTARGUMENT是调用事件时的参数

下面演示下如何调用后台事件:

1.
新建工程

2.
拖入一个服务端Button1,一个DropDownList1和一个客户端
Button
3.
设置DropDownList1AutoPostBack属性为True,Button1Visible
False
4.
双击Button1,在事件里写下
Response.Write("hello:" );
5.
页面的HTML里找到客户端Button,写入
onclick="__doPostBack('Button1','')"
6.
编译,运行,点击Button是不是出现了
"Hello"
7.
查看源代码,发现里面多了下面行

<script language="javascript">
<!--
    
function __doPostBack(eventTarget, eventArgument) {
        
var theform;
        
if (window.navigator.appName.toLowerCase().indexOf("netscape") > -1) {
               theform = document.forms["Form1"];
           }
        
else {
               theform = document.Form1;
           }
           theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
           theform.__EVENTARGUMENT.value = eventArgument;
           theform.submit();
       }
// -->
</script>

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



细心的人会发现,在__doPostBack里,提交调用的是theform.submit(),这样就导致对Formonsubmit事件校验失效了, 幸好这个问题在asp.net 2.0已经修复了。这里提供一个替换的解决办法,在Form的最下面插入下面的代码,这段代码在保证不管是不是render出来的页面均有效

            <script language="javascript">
<!--
    
function __doPostBack_Ex(eventTarget, eventArgument)
    
{
        
var theform;
        
if (window.navigator.appName.toLowerCase().indexOf("netscape") > -1) {
               theform = document.forms[0];
           }
        
else {
               theform = document.forms[0];
           }

        
if(!theform.__EVENTTARGET)
        
{            
               theform.appendChild(document.createElement("<input type='hidden' name='__EVENTTARGET'>"));
           }
        
        
if(!theform.__EVENTARGUMENT)
        
{            
               theform.appendChild(document.createElement("<input type='hidden' name='__EVENTARGUMENT'>"));                        
           }
        
           theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
           theform.__EVENTARGUMENT.value = eventArgument;
        
if ((typeof(theform.onsubmit) == "function"))
        
{
            
if(theform.onsubmit()!=false)
            
{
                   theform.submit();    
               }
           }
        
else
        
{            
               theform.submit();    
           }
        
        
function __doPostBack(eventTarget, eventArgument)
        
{
               __doPostBack_Ex(eventTarget, eventArgument);
           }
        

       }
// -->