浅谈ASP.NET的Postback

一  先来学习服务器控件Button里的一个属性UseSubmitBehavior
例如
<asp:Button runat="server" ID="Button1" Text="Button1" OnClick="Button1_Click" OnCommand="Button_Command" CommandArgument="Button1" />
<asp:Button runat="server" ID="Button2" Text="Button2" OnClick="Button2_Click" OnCommand="Button_Command" CommandArgument="Button2" UseSubmitBehavior="false" />

上面的代码转换成HTML文档后为
<input type="submit" name="Button1" value="Button1" id="Button1" />
<input type="button" name="Button2" value="Button2" onclick="javascript:__doPostBack('Button2','')" id="Button2" />

知道区别了吧!

二  这篇Blog的主旨就是从方法调用的角度讲述整个程序运行的过程
(1)从HTML被Render到Client端
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title></title>
</head>
<body>
    <form name="form1" method="post" action="Default.aspx" id="form2">
        <div>
            <input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
            <input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
            <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTc1NDI3NTEyM2RkGj9/23agZIp/SAWcuSSXy5I5f0Y=" />
        </div>

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

        <div>
            <span id="Span1" style="color:Red;"></span>
        </div>
        <div>
            <input type="submit" name="Button1" value="Button1" id="Submit1" />
            <input type="button" name="Button2" value="Button2" onclick="javascript:__doPostBack('Button2','')" id="Button2" />
        </div>
   
        <div>
         <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAwL55qqtDAKM54rGBgK7q7GGCLRU1V4jiX3ipoZg4a2i2nIkIQow" />
        </div>
    </form>
</body>
</html>

上面的HTML分为3部分
(1)第一部分 定义了3个hidden
<div>
    <input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
    <input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
    <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTc1NDI3NTEyM2RkGj9/23agZIp/SAWcuSSXy5I5f0Y=" />
</div>
说明:
__EVENTTARGET        触发事件的控件名
__EVENTARGUMENT    事件数据类
__VIEWSTATE           ViewState
参考:

事件变量 XXX
委托 XXXHandler
事件数据类 XXXEventArgs    (这个类必须从System.EventArgs中派生)
事件处理函数 OnXXX

委托的参数里有事件处理类,默认为EventArgs

(2)第二部分 一段JavsScript脚本
<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>
说明:
定义了一个__doPostBack function完成Postback的操作,该function只有区区3行代码,前两行通过参数对上面定义的两个hidden field赋值,然后向Server端提交表单

(3)第三部分 我们创建的控件
<div>
    <span id="Span1" style="color:Red;"></span>
</div>
<div>
    <input type="submit" name="Button1" value="Button1" id="Submit1" />
    <input type="button" name="Button2" value="Button2" onclick="javascript:__doPostBack('Button2','')" id="Button2" />
</div>
说明:
第一个Button以submit方式提交
第二个Button以javascript方式提交
    
(2)到用户Click某个按钮,输入被Postback到Server端,并触发两个Event,执行事件处理函数,打印出相关的Message
     在客户端,当我们点击Button2时,调用__doPostBack,传递2个参数,第一个为触发事件的控件名,此时为Button2;第二个为事件数据类,我们不需要传递额外的参数,因此为空;然后向服务器提交form,完成PostBack
     在服务器端,通过.__EVENTTARGET的Value找到对应的Server端的Control,通过Reflection确定该Control是否实现了System.Web.UI.IPostBackEventHandler接口.如果实现了该接口,那么调用Page.RaisePostBackEvent方法,该方法是一个Virtual方法,可以被Override,我们先来看看该方法的定义
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
{
    sourceControl.RaisePostBackEvent(eventArgument);
}

此例中sourceControl为Button2,eventArgument为空字符串
Button2的类型是System.Web.UI.WebControls.Button,我们来看看System.Web.UI.WebControls.Button中的RaisePostBackEvent方法的定义
protected virtual void RaisePostBackEvent(string eventArgument)
{
    //验证客户端事件
    base.ValidateEvent(this.UniqueID, eventArgument);
    //Button.CausesValidation属性 该值指示在单击Button控件时是否执行验证
    if (this.CausesValidation)
    {
        //Page.Validate方法 指示该页上包含的所有验证控件验证指派给它们的信息
        this.Page.Validate(this.ValidationGroup);
    }
    this.OnClick(EventArgs.Empty); //引发Click事件
    this.OnCommand(new CommandEventArgs(this.CommandName, this.CommandArgument)); //引发Command事件
}

这个方法也很简单,先进行验证,然后先后调用2个事件处理函数:OnClick和OnCommand,这和我们输出的结果是吻合的.

三  一些有趣的改动(一客户端)
既然我们已经知道Client端与Server端的交互是通过Form Submitting,那么,我们自己添加一小段JavaScript代码,如下
<script type="text/javascript" language="javascript">
    function postback()
    {
        __doPostBack('Button1','');
    }
    document.getElementById("Button2").onclick = postback;
</script>

此段JavaScript代码使得无论你点击那个Button,程序都认为你点击了Button1.
注意:上面的代码只能加到body中,不能加到head中,要好好领悟为什么不能(答案见文章 ... )!

四 一些有趣的改动(二服务器端)
三是在客户端实现无论你点击那个Button,程序都认为你点击了Button1.
下面在服务器端实现
override方法RaisePostBackEvent
protected override void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
{
    sourceControl = this.Button1;
    base.RaisePostBackEvent(sourceControl, eventArgument);
}

参考文章
浅谈ASP.NET的Postback
    http://www.cnblogs.com/artech/archive/2007/04/06/702658.html

posted on 2007-06-08 15:43  小乔的闺房  阅读(482)  评论(0编辑  收藏  举报

导航