dopostBack机制(转)

关于JS访问后台代码的文章已有很多了,基础知识请参看这里ASP.NET中前台javascript与后台代码调用,这篇文章主要介绍如何利用dopostpack来实现自己的一些应用

  dopostpack要调用系统生成的一些JS代码,这些代码我们自己没能力写出来,直接调用就行了。需要的就是在页面上添加哪些代码,才能正确的重现。dopostback主要是利用两个隐藏域和一段JS代码:

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

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

  我们要做的,就是不要系统生成,手动把这些内容添加到页面上,放到form的下面就可以了

  下面为窗体添加控件,分别使用了html的text,button及服务器端的textbox,button

  <input id="Text1" type="text" />
       <input onclick="formsubmit()"  id="Button" type="button" value="button" /><br />
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <input onclick="formsubmit1()"  id="Button1" type="button" value="button1" /><br />
        <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
        <asp:Button ID="Button2" runat="server" Text="Button2" OnClientClick="formsubmit2()" /><br />
        <input id="Text2" type="text" />
        <asp:Button ID="Button3" runat="server" Text="Button3" OnClientClick="formsubmit3()" /><br />

  这里我们使用服务器的button只是为了测试效果,实际上已经用不到了,完全采用JS的方式与服务器端交互,下面的这段JS加入页面的head区

<script>
      function formsubmit()
      {
          var temp = document.getElementById("Text1").value;
          __doPostBack('Button_Click', temp);
      }

      function formsubmit1() {
          var temp = document.getElementById("TextBox1").value;
          __doPostBack('Button1_Click', temp);
      }
      function formsubmit2() {
          __doPostBack('Button2_Click', '');
      }
      function formsubmit3() {
          var temp = document.getElementById("Text2").value;
          __doPostBack('Button3_Click', temp);
      }
</script>

  这些JS就是调用了dopostback方法,不同的是我们是自己写上的,可以加入参数,而参数不必是服务器控件里的内容,html控件的也可以。打开相应的cs文件,写上以下代码

protected void Page_Load(object sender, EventArgs e)
    {
        if (this.IsPostBack)
        {
            string target = Request.Params["__EVENTTARGET"];
            string args = Request.Params["__EVENTARGUMENT"];
            object[] obj = null;
            if (target.Trim() == "Button2_Click")
            {
                obj = new object[] { Button2, new EventArgs() };
            }
            else if (target.Trim() == "Button3_Click")
            {
                obj = new object[] { Button3, new EventArgs(),args };
            }
            else
            {
                obj = new object[] { args };
            }
            BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
            Type type = typeof(Default3);
            MethodInfo click =type.GetMethod(target, bindingAttr);

            if (click != null)
            {
                click.Invoke(this, obj);
            }
        }

    }

  要注意的是,您可能已经习惯了在page_load里写上if(!page.ispostback),而这里是要判断这是回传的,if(page.ispostback)。先用两个string把隐藏域的值取出来,然后用反射直接调用相应的方法,当然这里也可以用if,else的方式了,不过如果页面上的回传多的话可是一件痛苦的事情。个人感觉用if else,如果调用的方法少,比反射的性能要好。

  因为我们写的四个方法的参数不同,所以在为obj数组赋值的时候加了判断。这里的四个方法名称当然是可以随意的了,不过要和前台的JS代码相呼应,也就是__dopostback方法的第一个参数
    public void Button_Click(string args)
    {
        Response.Write("bclick " + args);
    }
    public void Button1_Click(string args)
    {
        TextBox1.Text = "b1click " + args;
    }
    public void Button2_Click(object sender, EventArgs e)
    {
        TextBox2.Text = ((System.Web.UI.WebControls.Button)sender).Text + " " + TextBox2.Text;
    }
    public void Button3_Click(object sender, EventArgs e,string value)
    {
        Response.Write( ((System.Web.UI.WebControls.Button)sender).Text + " " + value);
    }

  这里可以看到,button2的方法已经和系统生成的一致了,而button3的则是增加了一个参数

  现在就可以运行了,您可以分别在四个文本框中输入值并点击按钮测试。

  这个测试也许实际意义不大,只是帮助了解.net的一些工作原理,能应用到实际中当然更好,那就是智者见智的事了

  示例代码下载:dopostback.rar

posted @ 2012-06-27 09:22  网络虫  阅读(444)  评论(0编辑  收藏  举报