ASP.NET AutoPostBack然后返回Back Button很奇怪

为了简单起见,我在ASP.NET表单中有一个下拉列表和一个按钮。 下拉列表具有一个autopostback函数,该函数调用DropDownList1_SelectedIndexChanged并将页面重定向到某个地方(对于此示例www.google.com),该按钮具有一个转到Button1_Click1的onclick,页面将重定向到www.yahoo.com。

问题:如果我点击按钮,我会去雅虎,这是你所期望的。 如果我在浏览器中单击后退按钮并选择下拉列表,我会转到Google,这也是正确的,但如果我单击后退按钮然后单击按钮,我将重定向到Google。 呃? 为什么不去雅虎?

这是我的代码:

    Testing Auto-Postback   
Please select Go to Google

代码背后:

 using System; public partial class test : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) { Response.Redirect("http://www.google.com"); } protected void Button1_Click1(object sender, EventArgs e) { Response.Redirect("http://www.yahoo.com"); } } 

如果有人能帮助我,我将非常感激。

好吧,经过一番挖掘后,我发现了以下内容:

当我们单击Button ,直到Button1_Click1事件被引发的页面生命周期发生如下:

 Begin PreInit End PreInit Begin Init End Init Begin InitComplete End InitComplete Begin LoadState End LoadState Begin ProcessPostData End ProcessPostData Begin PreLoad End PreLoad Begin Load End Load Begin ProcessPostData Second Try End ProcessPostData Second Try Begin Raise ChangedEvents End Raise ChangedEvents Begin Raise PostBackEvent Raised Button1_Click1 // Button event here 

现在,当我们更改DropDownList ,直到DropDownList1_SelectedIndexChanged事件被引发的页面生命周期发生如下:

 Begin PreInit End PreInit Begin Init End Init Begin InitComplete End InitComplete Begin LoadState End LoadState Begin ProcessPostData End ProcessPostData Begin PreLoad End PreLoad Begin Load End Load Begin ProcessPostData Second Try End ProcessPostData Second Try Begin Raise ChangedEvents Raised DropDownList1_SelectedIndexChanged // DropDownList event here 

通过对页面生命周期进行分析,我们看到DropDownList1_SelectedIndexChanged事件是在Page’RovedEvents’过程中引发的,此方法比引发Button1_Click1事件的Page’PostBackEvent’过程更早发生。

现在,当您更改DropDownList SelectedIndex时,您将被重定向到Google。 当您点击后退按钮时,浏览器将检索该页面的最后一个状态,这意味着DropDownList将保留您之前更改的值。 如果在该阶段单击该按钮,则会在请求值上发送DropDownList和Button。 在首先引发DropDownList事件时,页面将再次重定向到Google。

更新:

一项工作可以在后面的代码上实现以下内容:

 public partial class test : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected override void OnInit(EventArgs e) { base.OnInit(e); if (IsPostBack) { //If the form is posting the button, it means you clicked it bool isButtonPostBackEvent = Request.Form.AllKeys.Contains(Button1.UniqueID); //Gets the posted value of the DropDownList string selectedValue = Request.Form[DropDownList1.UniqueID]; //Retrieves the index of the DropDownList postedValue int valueIndex = DropDownList1.Items.IndexOf(DropDownList1.Items.FindByValue(selectedValue)); //Verify if posted value of the dropdownlist is different from the server (will raise the SelectedIndexChangedEvent event) bool willRaiseSelectedIndexChangedEvent = DropDownList1.SelectedIndex != valueIndex; //Verifies if both events will be fired, so apply the button //behavior, otherwise let the asp.net do its //magic and raise the events automatically if (isButtonPostBackEvent && willRaiseSelectedIndexChangedEvent) { RedirectToYahoo(); } } } protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) { RedirectToGoogle(); } protected void Button1_Click1(object sender, EventArgs e) { RedirectToYahoo(); } private void RedirectToGoogle() { Response.Redirect("http://www.google.com"); } private void RedirectToYahoo() { Response.Redirect("http://www.yahoo.com"); } } 

在OnInit事件中,代码标识将由asp.net引发的事件。 当两个事件都存在时,我们应用按钮单击行为,因为它在这种情况下具有优先级(单击它)。

如果你不介意,你也可以更简单:

 protected override void OnInit(EventArgs e) { base.OnInit(e); if (IsPostBack) { bool isButtonPostBackEvent = Request.Form.AllKeys.Contains(Button1.UniqueID); if (isButtonPostBackEvent) { RedirectToYahoo(); } } }