当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > Request.Form中的一些特殊的东西

ASP.NET
不同映射模式下的直线输出的效果问题
ASP.NET开发下的MVC设计模式的实现
ASP.NET编写应用程序的十大技巧
ASP.NET中使用AJAX的简单方法
ASP.NET MVC实现自己的视图引擎
认识asp.net会话状态
ASP.NET实现页面传值的几种方法
.NET中容易混淆的几组重要概念
详解.NET中的动态编译技术
如何使用ASP.Net加密Cookie
ASP.NET 2.0跨网页提交的三种方法
ASP.NET 2.0创建母版页引来的麻烦
.Net整合其他平台的一些探讨
ASP.NET编程经验技巧10则
最佳实践 ADO.NET实用经验无保留曝光
在.NET上执行多线程操作要考虑的两大因素
.Net开发 细说Visual Basic.Net
ASP.NET网络编程中经常用到的27个函数集
ASP.NET防止用户多次登录的方法
对ASP.NET MVC项目中的视图做单元测试

ASP.NET 中的 Request.Form中的一些特殊的东西


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 74 ::
收藏到网摘: n/a

在page_load的时候怎么知道是按了哪个按钮?

一个form runat = server
里面有很多button
bunton1,bunton2,bunton3...

我怎么知道是点了哪个button返回的呢?
  
问题太模糊了,你用的是 服务端控件还是客户端的呢?服务端的直接写它的单击事件就可以了。客户端的就用js。

服务器端的,我就是要在page_load的时候知道它接下来执行哪个函数。
我知道可以写button的click事件

你是新新新手吧
page_load 是页面夹暂时候执行的吧

按牛提交都回有自己的名字的。。。

按钮的点击事件属于postback了,page_load只是页面加载的时候激发的事件,我还是不明白你想要什么,能不能贴点代码上来看看

这么说吧:
protected void Page_Load(object sender, EventArgs e)
{
//在这里我有没有可能得到接下来执行的哪个方法? 是btn1还是btn2,还是根本就不可能得到?
}
protected void btn1_Click(object sender, EventArgs e)
{
      
}
protected void btn2_Click(object sender, EventArgs e)
{
      
}

不可能
因为先是page_load事件之后,再执行按钮中的click事件
既然page_load在先,那么就不可能知道这以后要发生的事情


不可能
因为先是page_load事件之后,再执行按钮中的click事件
既然page_load在先,那么就不可能知道这以后要发生的事情
那.NET本身是通过什么机制来知道接下来发生的事情的呢?

那.NET本身是通过什么机制来知道接下来发生的事情的呢?
通过 EventArgs e,你只有按了以后会产生事件,这个时候能捕捉,你pageload的时候按钮就没按,谁会知道啊,你以为是神啊,所以你逻辑混乱关系混乱。先把net的事件,委托看明白了再来说问题。

pageload里面有个Page.postback 楼主了解吧

你可以设置button的commandargs属性
override protected void OnInit(EventArgs e)
    {
this.btn1.Command += new CommandEventHandler(this.DoBtnClick);
}
public virtual void DoBtnClick(object sender, CommandEventArgs e)
    {
string btn= e.CommandArgument.ToString();
switch(btn){}

}

我在7楼中说道:
不可能
因为先是page_load事件之后,再执行按钮中的click事件
既然page_load在先,那么就不可能知道这以后要发生的事情

然后楼主在8楼问道:
那.NET本身是通过什么机制来知道接下来发生的事情的呢?
看到这个,我也很郁闷。。。但是不知道该如何回答。

突然在昨晚,我在调试的时候发现了Request.Form中的一些特殊的东西:Page.Request.Form["__EVENTTARGET"]

我觉得在Page_Load中确定当前的postback是由谁引起的,便不是难事了。
分析一下生成的html源码,发现linkbutton生成后是这样的:

<a id="LinkButton1" href="javascript:__doPostBack('LinkButton1','')">Button2</a>

而doPostBack的函数是这样的:

function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}

在Form的隐藏标记还可以发现这些:

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

也就是说,linkbutton的id要提交到服务器端去,那在服务器端的Page_Load中不就可以确定是谁postback的了。

但是,Button和ImageButton在提交时,Page.Request.Form["__EVENTTARGET"]的值却是空的。
不过,既然LinkButton提交时它的ID要提交到客户端,那么Button理应也该提交上去
Button的客户端代码是:

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

也就是说,Button在提交时,其本身也是input标签,提交表单时它自身当然也要提交上去了。

只要我们在Request.Form循环提交来的字符串,再用这个字符串FindControl就行了。
下面就是在page_load中寻找控件的函数。

    private string getPostBackControlName()
    {
        Control control=null;
        string ctrlname = Page.Request.Params["__EVENTTARGET"];
        if (ctrlname != null && ctrlname != String.Empty)
        {
            control = Page.FindControl(ctrlname);
        }
        else
        {
            Control c;
            foreach (string ctl in Page.Request.Form)
            {
                if (ctl.EndsWith(".x") || ctl.EndsWith(".y"))
                {
                    c = Page.FindControl(ctl.Substring(0, ctl.Length - 2));
                }
                else
                {
                    c = Page.FindControl(ctl);
                }
                if (c is System.Web.UI.WebControls.Button ||
                         c is System.Web.UI.WebControls.ImageButton)
                {
                    control = c;
                    break;
                }
            }
        }
        if (control != null)
            return control.ID;
        else
            return string.Empty;
    }

OK,暂时没问题,但是,如果Button在GridView、Repeater等控件中又会怎么样呢?

这得用过另一个了:Page.Request.Params["__EVENTARGUMENT"]

上面一个图就是在GridView中单了击第二行中的“选择”按钮,所以提交到服务器的Page.Request.Params["__EVENTARGUMENT"]值为"Select$1",很明显,如果单击的是第一行,这个值应该为"Select$0"
所以在GridView中的LinkButton的寻找是没有问题的,那是不是Button、ImageButton与LinkButton有区别呢?
答案是 没有。
因为LinkButton、Button和ImageButton都使用的是javascript的__doPostBack
它们生成的html标签可能像下面这样:

<a href="javascript:__doPostBack('GridView1','Edit$0')">编辑</a>
<input type="button" value="编辑" onclick="javascript:__doPostBack('GridView1','Edit$1')" />
<input type="image" src="" alt="编辑" onclick="javascript:__doPostBack('GridView1','Edit$1')" style="border-width:0px;" />

所以,结论

在Page_Load中,可以确定当前的POSTBACK是由谁引起的,而查找它们的方法就在上面的code的给出;
如果控件位于其它控件中,比如GridView、Repeater、DataList等等,就需要由Request.Params["__EVENTARGUMENT"]来帮助确定这个控件名,否则从Request.Form["__EVENTTARGET"]获得的将会是GridView1, Repeater1之类的数据控件的ID,而不是具体的引起POSTBACK的Button。

注:在写的时候,我GG了一下,发现了已有一篇这样的文章,于是,我参考了他的代码,上面的代码也稍稍作了些修改:
Get control name in Page_Load event which make the post back