页面文件:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>    <form id="form1" runat="server">
    <div>
        <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
    </div>
    </form>
</body>
</html>
后台
        protected void Page_Load(object sender, EventArgs e)
        {
            foreach (Control item in this.form1.Controls)
            {                if (item is Button)
                {
                    Button btn = item as Button;
                    btn.Click += delegate(object s, EventArgs ea)
                    {
                        // 写日志的代码
                        getsss();
                    };
                }
            }            
        }        public void getsss()
        {
            //日志
        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            Response.Redirect("http://www.baidu.com");
        }我的目的是:当点击button1后,执行button_click方法,再执行getsss()日志方法
目前问题:当Button1_Click无跳转页面的时候,一切正常
          当Button1_Click跳转的时候,无法执行getsss()方法请高手们解决下

解决方案 »

  1.   

     protected void Button1_Click(object sender, EventArgs e)
      {
      Response.Redirect("http://www.baidu.com");
      getsss();
      }
    自己跟一下代码咯,我觉得吧,跳转页面之后,后面的getsss()方法是不会执行的。
      

  2.   

    我试验过了,Response.Redirect后面的代码不会执行了,请问下,如何能解决下,或者
    btn.Click += delegate(object s, EventArgs ea)
    如何让先执行我的方法,然后再执行click事件?
      

  3.   

    btn.Click += delegate(object s, EventArgs ea)
    这表明你把处理逻辑放在了委托链表的末尾,而链表是按顺序进行处理的,所以其会先执行Button1_Click,而Button1_Click中Redirect表明已经跳出了页面的处理逻辑,之后的处理可能不会执行。
    你应该想办法把Button1_Click加入到链表的最后才可以。
      

  4.   


    可以先让你的代码执行的实际上,Button1_Click 也是绑定到对象上去的
    用 Web 项目的方式开发(而不是以网站形式开发)的时候就可以看到这个绑定语句,在页面对应的 .disign.cs 文件里从这里着手去解决这个问题应该是可以的比如,写一个基类,将你的钩子语句放在初始化阶段(所有控件添加完毕,但还没有为其绑定事件时),把你的事件处理放在页面绑定事件之前
      

  5.   

    string script = " <script language='javascript'>window.open('login.aspx');" +
                      "window.parent.opener = null;window.parent.open('','_self');window.parent.close(); window.close(); </script>";
                    Response.Write(script);
                   getsss();
      

  6.   

     string script = " <script language='javascript'>window.open('login.aspx');" +
                      "window.parent.opener = null;window.parent.open('','_self');window.parent.close(); window.close(); </script>";
                    Response.Write(script);
                 getsss();
      

  7.   

    把页面的button的onclick按钮事件删除,统一通过代码绑定,如下:
    protected void Page_Load(object sender, EventArgs e)
    {
        foreach (Control item in this.form1.Controls)
        {
            if (item is Button)
            {
                Button btn = item as Button;            btn.Click += delegate(object s, EventArgs ea)
                {
                    // 写日志的代码
                    getsss();
                };
            }
        }
        Button1.Click += Button1_Click;
    }
      

  8.   

    Response.Write(script);可以解决,但是还是要修改以前的代码,以前代码修改的地方很多,很多用的都是Redirect把页面的button的onclick按钮事件删除,统一通过代码绑定,这个方法改动量太大了
      

  9.   

    目前是项目已经完工了,我要在尽量不改动原来代码的基础上加上按钮操作日志,目前所有的页面都继承了pagebase的基类,如果在pagebase基类里加入btn.Click += delegate(object s, EventArgs ea),可以在不改动代码的情况下,加入日志功能。
    但是,发现,有的按钮是进行了跳转,
    所以想办法把Button1_Click加入到链表的最后,这个方法我觉得还是可行,就是不知道怎么做
      

  10.   

    可以这样做:
    protected void Page_Load(object sender, EventArgs e)
    {    
        foreach (Control item in this.form1.Controls)
        {
            if (item is Button)
            {
                Boolean delEvent = false;//标记是否剔除了其中的Button1_Click处理事件
                Button btn = item as Button;
                try
                {
                    FieldInfo f1 = typeof(Button).GetField("EventClick", BindingFlags.Static | BindingFlags.NonPublic);
                    object obj = f1.GetValue(btn);
                    PropertyInfo pi = btn.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
                    EventHandlerList list = (EventHandlerList)pi.GetValue(btn, null);                
                    foreach (Delegate d in list[obj].GetInvocationList())
                    {
                        if (d.Method.Name == "Button1_Click")
                            btn.Click -= Button1_Click;
                        delEvent = true;//标记已经删除过Button1_Click
                    }
                }
                catch (Exception ex)
                {
                    //必须进行出错检测和处理,因为并不是所有的Button都有EventClick都有属性值
                }
                btn.Click += delegate(object s, EventArgs ea)
                {
                    // 写日志的代码
                    getsss();
                };
                if (delEvent)//若之前删除过Button1_Click事件,则在事件队列最后添加上
                {
                    btn.Click += Button1_Click;
                    delEvent = false;
                }            
            }
        }  }具体可参考一下:
    http://stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control
      

  11.   

    最简单的方法就是在click事件中比如这样:  protected void Button1_Click(object sender, EventArgs e)
      {
      Response.Redirect("http://www.baidu.com");
      }
    改为:
      protected void Button1_Click(object sender, EventArgs e)
      {
     getsss();
      Response.Redirect("http://www.baidu.com");
      }不就行了啊
      

  12.   

    楼主是不管咋样都要先执行getsss();????
    这样子能满足楼主需求不?
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="JS调用后台方法._Default" %><!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 runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
        <asp:Button ID="Button1" runat="server" Text="Button" OnClientClick="return getsss()" onclick="Button1_Click" />
        </div>
        
        </form>
    </body>
    </html><script type="text/javascript">
        function getsss() {
            var a = "<%=getsss() %>"
            return true;
        }
    </script>using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;namespace JS调用后台方法
    {
        public partial class _Default : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {        }        protected void Button1_Click(object sender, EventArgs e)
            {        }
            protected string  getsss()
            {
                return "OK";
            }
        }
    }
      

  13.   

    gx的例子很不错,能满足我的要求
    有一个问题,不是所有的按钮方法都是Button1_Click,你的程序我是要写在pagebase里,所以
    if (d.Method.Name == "Button1_Click")
    这个语句不对能否有个比较完美的方法
      

  14.   


    我是想在不大范围更改程序的情况下执行,就好像是我要把getsss()这个方法注入到所有的按钮事件里一样
      

  15.   


    protected override void OnPreInit(EventArgs e)
        {
            if (IsPostBack)//服务端控件引起回发
            {
                if (Request["__EVENTTARGET"] == null)//确认是button引起的回发
                {
                    foreach (string str in Request.Form)
                    {
                        Control c = Page.FindControl(str);
                        if (c is Button)
                        {
                            Log(c.ID);
                        }
                    }
                }
               
            }
        }    private void Log(string controlID)
        {
            Response.Write(string.Format("{0}引起的Common Click",controlID));
        }注意把上面的方法放到你的pagebase中,log指的就是你的getsss方法
      

  16.   

    其实本质就是在你的任何页面的button click事件触发之前,写执行getsss方法。
      

  17.   

    请问chen_ya_ping,你的程序对<asp:LinkButton是怎么处理的?我试验了下,if (c is LinkButton)
                        {
                            Log(c.ID);
                        }
    这样执行不到,这是为什么?
      

  18.   

    很是奇怪呀
    <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
            <asp:LinkButton ID="LinkButton1" runat="server" onclick="button_insert_Click">LinkButton</asp:LinkButton>
            <asp:Button id="OKButton" runat="server" CssClass="Button" Text=" 确   定 " onclick="Button1_Click"/>如果页面带有linkbutton,原Button的方法也会失效
    请问下如何解决下
      

  19.   


    protected override void OnPreInit(EventArgs e)
        {
            if (IsPostBack)//服务端控件引起回发
            {
                if (Request["__EVENTTARGET"] == null)//确认是button引起的回发
                {
                    foreach (string str in Request.Form)
                    {
                        Control c = Page.FindControl(str);
                        if (c is Button)
                        {
                            Log(c.ID);
                        }
                    }
                }
                else
                {
                    Log(Request["__EVENTTARGET"].ToString());
                }
               
            }
        }其他的都不变
      

  20.   


    这里能否改善下
    if (d.Method.Name == "Button1_Click")
                                btn.Click -= Button1_Click;
    这里能否用反射机制,直接btn.Click -= d.Method.Name;而这里直接用btn.Click += d.Method.Name;请问下能这样实现吗?如何写这块代码?
      

  21.   

    if (d.Method.Name == "Button1_Click")
      btn.Click -= Button1_Click;如果button很多,if就多了啊。
      

  22.   


    你这个方法还是不错的,目前的服务器按钮控件几乎都捕捉到了,还有一个问题Log(Request["__EVENTTARGET"].ToString());
    这个参数能否传个对象进去?也就是Log(按钮对象)
    或者变通点,传个Log(button.id,button.text)
      

  23.   

    我好像知道怎么弄了,Page.FindControl(Request["__EVENTTARGET"])这样就行了,我这么写对吧?chen_ya_ping
      

  24.   

    Request["__EVENTTARGET"] == null为啥确定就是Button呢?不解,这个肯定不是空的啊
      

  25.   

    不知道你需要什么效果?
    难道涉及的按钮事件不一样,而且想放到pagebase中作为一个共用的处理?
      

  26.   


    是这样的,chen_ya_ping的那个方法是否有什么问题,我在程序里写,还没发现问题,只是有个疑问protected override void OnPreInit(EventArgs e)
        {
            if (IsPostBack)//服务端控件引起回发
            {
                if (Request["__EVENTTARGET"] == null)//确认是button引起的回发
                {
                    foreach (string str in Request.Form)
                    {
                        Control c = Page.FindControl(str);
                        if (c is Button)
                        {
                            Log(c.ID);
                        }
                    }
                }
                else
                {
                    Log(Request["__EVENTTARGET"].ToString());
                }
               
            }
        }
    if (Request["__EVENTTARGET"] == null)//确认是button引起的回发
    这句我没看明白,目前我测试的都不是null,要么是空,要么是id值
      

  27.   


    if (Request["__EVENTTARGET"] == null)//确认是button引起的回发
    这句我没看明白,目前我测试的都不是null,要么是空,要么是id值
    我现在是这样处理的,
    if (Request["__EVENTTARGET"] is Button ||Request["__EVENTTARGET"] is LinkButton){
           //写日志
    }
    不知我这样写是否有问题?
      

  28.   

    如果你的页面有button的时候,没有其他的会引起回发的事件的控件,你就知道什么地方会有问题了。
    可以看看postback这个内容,对你有帮助。
      

  29.   

    当页面会引起回发的控件不只是Button的时候,如页面上既有Button,又有LinkButton,这样Request["__EVENTTARGET"]的结果为空
    这种情况就判断不出c is Button了,Page.FindControl(Request["__EVENTTARGET"]的结果也是个空,求这种情况的解决方法
      

  30.   

    当页面会引起回发的控件不只是Button的时候,如页面上既有Button,又有LinkButton,当点击Button的时候Request["__EVENTTARGET"]是空,当点击LinkButton的时候,Request["__EVENTTARGET"]是LinkButton的ID
    这是为什么?
      

  31.   

    我就不解释了,给你找篇文章
    http://www.blueidea.com/tech/program/2008/5291.asp
    http://geekswithblogs.net/mahesh/archive/2006/06/27/83264.aspx不过文中的实现方式有待商榷,如果你的button 能确定层级的话那可以弃用FindControl ,当做字符串遍历即可。
      

  32.   

    thanks,Sandy945,你推荐的文章很好,我试验下
      

  33.   


    是这样的,如果页面上是这样的<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
            <asp:LinkButton ID="LinkButton1" runat="server" onclick="button_insert_Click" Text="LinkButton111111">LinkButton</asp:LinkButton>
            <asp:Button id="OKButton" runat="server" CssClass="Button" Text=" 确   定 " onclick="Button1_Click"/>这个时候,点击Button1或OKButton,则你方法里的
    Log(Request["__EVENTTARGET"].ToString());

    Request["__EVENTTARGET"]是空,要不你那测试下
      

  34.   

    问题解决了,最后改了下网上的程序
    if (IsPostBack)//服务端控件引起回发
            {            //参考资料
                Control control = null;
                if (Page.Request.Params["__EVENTTARGET"] != null && Page.Request.Params["__EVENTTARGET"] != String.Empty)
                {
                    control = Page.FindControl(Page.Request.Params["__EVENTTARGET"]);
                }            else
                {
                    Control c;                //System.Collections.Specialized.NameValueCollection aa = Page.Request.Form;                string bb = Page.Request.Form.ToString();                               //foreach (string ctl in aa)
                    foreach (string ctl in bb.Split(new char[1] { '&' }))
                    {
                        string text = ctl.Split(new char[1]{'='})[0];
                        if (text.EndsWith(".x") || text.EndsWith(".y"))
                        {
                            c = Page.FindControl(text.Substring(0, text.Length - 2));
                        }
                        else
                        {
                            c = Page.FindControl(text);
                        }
                        if (c is System.Web.UI.WebControls.Button ||
                                 c is System.Web.UI.WebControls.ImageButton)
                        {
                            control = c;
                            break;
                        }
                    }
                }            if (control != null)
                {
                    LogHelper.InsertSystemLog(control, null, null);
                }
            }
    因为我发现,如果遍历Page.Request.Form,会在某些情况下,使表单数据丢失最后结贴