2012-10-27 20 views
1

爲了保持這種簡單,我在ASP.NET窗體中有一個下拉列表和一個按鈕。下拉列表具有調用DropDownList1_SelectedIndexChanged的autopostback函數,並且該頁面被重定向到某處(對於此示例,www.google.com),並且該按鈕具有一個onclick,該按鈕將轉到Button1_Click1,並且該頁面被重定向到www.yahoo.com。ASP.NET AutoPostBack然後後退按鈕奇怪發生

問題:如果我點擊按鈕,我會去雅虎,這是你所期望的。如果我在瀏覽器中點擊返回按鈕並選擇下拉列表,我會轉到Google,這也是正確的,但如果我點擊後退按鈕,然後點擊按鈕,我將重定向到Google。呃?爲什麼不去雅虎?

這裏是我的代碼:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="test.aspx.cs" Inherits="test" %> 

<!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>Testing Auto-Postback</title> 
</head> 
<body> 
    <form id="form1" runat="server"> 

       <asp:DropDownList ID="DropDownList1" runat="server" onselectedindexchanged="DropDownList1_SelectedIndexChanged" AutoPostBack="true" ValidationGroup="form1"> 
       <asp:ListItem>Please select</asp:ListItem> 
       <asp:ListItem>Go to Google</asp:ListItem> 
       </asp:DropDownList> 

       <hr /> 

       <asp:Button ID="Button1" runat="server" Text="Go to Yahoo" 
        ValidationGroup="form2" onclick="Button1_Click1" /> 
    </form> 
</body> 
</html> 

代碼背後:

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"); 
    } 
} 

如果有人可以幫助我,那將是十分讚賞。

回答

1

好,一些挖後,我發現了以下內容:

當我們點擊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 

分析兩個頁面生命週期,我們看到頁面'ChangedEvents'過程中引發DropDownList1_SelectedIndexChanged事件,此方法發生在提早發生Button1_Click1事件的Page'PostBackEvent'過程之前。

現在,當您更改DropDownList SelectedIndex時,您將被重定向到Google。當您點擊後退按鈕時,瀏覽器將檢索該頁面的最後一個狀態,這意味着DropDownList將保留您之前更改的值。如果在這個階段你點擊了按鈕,DropDownList和按鈕都在請求值上發送。當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(); 
     } 
    } 
} 
+0

謝謝你看這個。有什麼辦法可以阻止這種情況發生? – Jefferson

+0

用可能的解決方法更新了答案。 –

+0

再次感謝您。這些解決方案完美地工作,第二個是輝煌的,我喜歡簡單。非常感謝! – Jefferson