ASP.NET AutoPostBack and then Back Button weird occurrence

核能气质少年 提交于 2020-01-23 19:24:32

问题


To keep this simple, I have a dropdownlist and a button in an ASP.NET form. The dropdownlist has an autopostback function that calls DropDownList1_SelectedIndexChanged and the page is redirected somewhere (for this example www.google.com) and the button has an onclick that goes to Button1_Click1 and the page gets redirected to www.yahoo.com.

The Problem: If I click the button, I go to Yahoo, which is what you'd expect. If I click back button in my browser and select the dropdownlist I go to Google which is also correct but if I click the back button and then click the button I get redirected to Google. Uh? Why doesn't it go to Yahoo?

Here's my code:

<%@ 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>

Code Behind:

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

If anyone could help me, it would be most appreciated.


回答1:


Well, after some digging, i found the following:

When we click the Button, the page life cycle till the Button1_Click1 event is raised happens like this:

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

Now, when we change the DropDownList, the page life cycle till the DropDownList1_SelectedIndexChanged event is raised happens like this:

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

Analising both page life cycles, we see that the DropDownList1_SelectedIndexChanged event is raised on the Page 'ChangedEvents' procedure, this method happens earlier than the Page 'PostBackEvent' procedure that raises the Button1_Click1 event.

Now, when you change the DropDownList SelectedIndex you are redirected to Google. When you hit the back button, the browser retrieves the last state of that page, meaning that the DropDownList will remain with the value you changed before. If, at that stage you click the button, both the DropDownList and the Button are being sent on the request values. As the DropDownList event is raised first, the page get redirected to Google again.

Update:

One work arround could be implement the following on the code behind:

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

On the OnInit event, the code identifies the events that will be raised by asp.net. When both events are present, we apply the button click behavior as it has the priority in this case (it was clicked).

If you don't mind, you could also do it simpler:

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);

    if (IsPostBack)
    {
        bool isButtonPostBackEvent = Request.Form.AllKeys.Contains(Button1.UniqueID);

        if (isButtonPostBackEvent)
        {
            RedirectToYahoo();
        }
    }
}


来源:https://stackoverflow.com/questions/13099906/asp-net-autopostback-and-then-back-button-weird-occurrence

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!