2012-02-03 49 views
5

后,我已经得到了部分由使用DropDownList控制导航的ASP.NET 2.0 Web应用程序。当其中一个更改时,会导致回发,然后根据在下拉列表中选择的内容将其重定向到另一个URL。使用回传浏览器的后退按钮

我使用的下拉菜单后,使用浏览器的后退按钮时发现奇怪的行为。程序是这样的:

  1. 在下拉列表中选择一个,导致回发和重定向。目前很好。
  2. 点击浏览器的后退按钮。
  3. 在另一个导航下拉菜单下面使用之前使用的一个(它们都包含在一个div),请做出选择。该页面首次重定向到相同的URL,而不是基于此其他下拉菜单重定向到的内容。

我已经在Firefox 10和IE9中试过这个,看过同样的东西。我查看了Firebug中的Net选项卡,并在步骤3的POST中看到引用了正确的控件。但是,当我调试它时,错误下拉的事件处理程序(步骤1中使用的那个)会触发。

的代码非常简单明了。标记的例子:

<asp:DropDownList runat="server" ID="ddlTest" AutoPostBack="true" /> 

的下拉列表实际上是不是纯<asp:DropDownList ... />元件;我使用类似于this的方法插入optgroup元素。 C#的

例子:

ddlTest.Click += new EventHandler(ddlTest_SelectedIndexChanged); 

而且在ddlTest_SelectedIndexChanged

if (ddlTest.SelectedValue != "") 
{ 
    Response.Redirect(MyUtilClass.GetUrl(ddlTest.SelectedValue)); 
} 

这是怎么回事吗?

更新2012年2月6日:我已经通过检查的Request["__EVENTTARGET"]SelectedIndexChanged事件处理程序的内容固定这一点。不过,我仍然很好奇它为什么会发生。为什么重复第一个事件?为什么只有当第二次回复发生在第一次回复发生时才会发生?

+0

你可以添加下拉页面的标签吗?有助于。 – 2012-02-04 00:11:19

+0

下拉列表的标签?你的意思是他们在页面上的ID?或者他们的标记?它看起来很像我在问题中发布的标记。 – 2012-02-04 00:20:34

+0

只是一个建议:即使没有使用后退按钮,您的导航栏也不会显示我所称的预期行为。通常,导航应该与您的内容同步。这样,当你点击一个学校名称时,那个学校就会在你的下拉菜单中被选中。事实上,我越看越感觉* * *。就好像你可以摆脱整个左侧导航(捕获房地产),并在顶部提供两个下降:学校和运动。无论如何,其他人完全依赖于该信息... $ 0.02为其价值。 – NotMe 2012-02-05 04:50:43

回答

3

一旦你上的后退按钮点击,因为它被保存在客户端上显示上次访问的页面不从服务器,这其中包括像你选择后的一次显示的最后发布的值送回/请再次/点击后退按钮后的第二个DropDownlist。

第一页的IE上的onload方法(对于其他浏览器参见:http://dean.edwards.name/weblog/2005/09/busted/)在第二页上按下后退按钮时被触发使用这个我们可以尝试在重定向页面之前在客户端保存回发操作,我们将它保存在一个带有JS的隐藏值中,然后一旦用户返回,onload方法将评估隐藏是否有值,如果是,则更改页面本身的位置,这样的页面再次请求和所有的贴值都会被清空了:

第1页。ASPX

<script type="text/javascript"> 
     function redir(){  
      var h=document.getElementById('hdR'); 
      if (h.value=='1'){ 
       h.value='0'; 
       document.location.href='page1.aspx'; 
      }   
     } 

     function changeHids(){ 
      var h=document.getElementById('hdR'); 
      h.value='1'; 
     } 
     </script> 
    </head> 
    <body onload="redir();"> 
     <form id="form1" runat="server"> 
     <div> 
      <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" onchange="changeHids();"> 
       <asp:ListItem>1</asp:ListItem> 
       <asp:ListItem>2</asp:ListItem> 
       <asp:ListItem>3</asp:ListItem> 
       <asp:ListItem>4</asp:ListItem> 
      </asp:DropDownList> 
      <br /> 
      <asp:DropDownList ID="DropDownList2" runat="server" AutoPostBack="true" onchange="changeHids();"> 
       <asp:ListItem>5</asp:ListItem> 
       <asp:ListItem>6</asp:ListItem> 
       <asp:ListItem>7</asp:ListItem> 
       <asp:ListItem>8</asp:ListItem> 
      </asp:DropDownList> 
      <asp:HiddenField ID="hdR" runat="server"/> 
     </div> 
     </form> 
    </body> 

Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList1.SelectedIndexChanged 

    Response.Redirect("page2.aspx?ddl=1&val=" & Me.DropDownList1.SelectedValue, True) 

End Sub 

Protected Sub DropDownList2_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList2.SelectedIndexChanged 

    Response.Redirect("page2.aspx?ddl=2&val=" & Me.DropDownList2.SelectedValue, True) 

End Sub 

page2.aspx

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 

     Response.Write("ddl:" & Request.QueryString("ddl") & " " & "value:" & Request.QueryString("val")) 

    End Sub 
2

可以使用Response.Cache属性来解决这个问题,因为你是允许缓存在浏览器内存列表中。从MSDN SetAllowResponseInBrowserHistory

当HttpCacheability被设定为nocache或ServerAndNoCache的 过期HTTP标头是默认设置为-1;这告诉客户端不要在 缓存历史记录文件夹中的响应,以便当您使用 后退/前进按钮时,客户端每次请求新版本的响应 。您可以通过调用允许参数集 为true的 SetAllowResponseInBrowserHistory方法来覆盖此行为。

在你的页面加载方法中,你添加了这一行。

protected void Page_Load(object sender, EventArgs e) 
    { 
     Response.Cache.SetCacheability(HttpCacheability.NoCache); 
     Response.Cache.SetAllowResponseInBrowserHistory(false); 

     // or else you can do like this 

     Response.ExpiresAbsolute = DateTime.Now.AddDays(-1d); 
     Response.Expires = -1; 
     Response.CacheControl = "No-cache"; 
    } 

这样,无论您何时按下,t都会每次请求一个新版本的响应。

+0

这看起来很不错。我已经更新了这个问题,以澄清我正在寻找的信息。 – 2012-02-06 19:06:21

+0

我尝试将前两行添加到我的Page_Load中,问题仍然存在。 – 2012-06-14 17:52:46

3

火狐 - 添加代码背后:

protected void Page_Load(object sender, EventArgs e) 
{ 
    Response.AppendHeader("Cache-Control", "no-store"); 
} 

浏览器 - 添加JavaScript页面加载:

var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1; 
if (is_chrome) { 
    document.getElementById("form1").reset(); 
} 
0

从@Ravi答案细微变化工作对我来说...

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

    Context.Response.AddHeader("Cache-Control", "max-age=0,no-cache,no-store"); 
    Context.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
    Context.Response.Cache.SetMaxAge(TimeSpan.Zero); 

    .... 
}