【问题标题】:ASP.NET AutoPostBack and then Back Button weird occurrenceASP.NET AutoPostBack 然后返回按钮奇怪的发生
【发布时间】:2012-10-27 11:49:37
【问题描述】:

为了简单起见,我在 ASP.NET 表单中有一个下拉列表和一个按钮。下拉列表有一个调用 DropDownList1_SelectedIndexChanged 的​​自动回发函数,并且页面被重定向到某个地方(例如 www.google.com),并且按钮具有转到 Button1_Click1 的 onclick 并且页面被重定向到 www.yahoo.com。

问题:如果我点击按钮,我会转到 Yahoo,这正是您所期望的。如果我在浏览器中单击后退按钮并选择下拉列表,我会转到 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");
    }
}

如果有人可以帮助我,将不胜感激。

【问题讨论】:

    标签: c# asp.net redirect webforms autopostback


    【解决方案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 事件的页面“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();
            }
        }
    }
    

    【讨论】:

    • 感谢您查看此内容。有没有办法阻止这种情况发生?
    • 再次感谢您。这些解决方案完美运行,第二个非常棒,我喜欢简单。非常感谢!
    • 不客气。如果它适合您的需要,您可以接受它作为答案。
    猜你喜欢
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多