【问题标题】:Gridview, and that pesky browser back buttonGridview,还有那个讨厌的浏览器后退按钮
【发布时间】:2011-11-07 16:49:57
【问题描述】:

我们的 ASP.NET 页面上有一个带有一些数据的 GridView,其中一列有 CheckBoxes 以便选择行。 GridView 下方存在一个删除按钮。当最终用户通过 CheckBoxes 选择一些项目,然后单击 Delete 按钮时,将触发回发并删除所选项目。很普通的东西。

分配给我的问题也很常见。如果在结果页面上,最终用户单击浏览器后退按钮,则(在总是被立即忽略的警告之后)重新启动回发。

这里的问题是,由于所选项目已被删除,浏览器只需选择现在占据已删除项目所在空间的任何行,然后继续删除这些项目。这是一件坏事™。

到目前为止,我一直在尝试基于设置和检查会话变量来尝试跟踪是否发生回发,但我对结果不太满意。

有没有人有处理这个问题的好方法(希望是简单的)?

【问题讨论】:

  • 这个页面是否使用Session来存储用户将要删除的选中项?或者,您是说,在发布已删除的项目后,浏览器正在(以某种方式)重新检查不再匹配相应项目的索引处的复选框?我不太清楚重新选中复选框的原因。
  • 对不起,这个问题慢慢回复,因为有其他问题。没有会话值用于此。复选框被选中然后提交 - 标准的 asp.net 东西。所以在这种情况下,假设我有 5 行,检查前两行,然后提交。前两行被删除。剩余的行现在在网格中“向上移动”,所以以前的第 3-4 行现在是第 1-2 行。单击后退按钮,然后再次提交。表单值仍然表明应该删除第 1-2 行,所以它确实如此。现在只剩下 1 行(在本例中)。
  • 那么,您通过type="submit" 按钮使用完整回发?可以贴一些相关的标记sn-ps和提交的C#/VB代码吗?

标签: asp.net gridview postback


【解决方案1】:

您还可以在第一个 !IsPostback 上将一些值与会话一起放入视图状态,然后在 IsPostback 中将其更改为其他内容。

这可能比 cookie 或浏览器缓存过期的东西更容易。

在这种情况下,如果用户单击后退按钮并提交任何内容,您可以查看 viewstate 并查看它是否与 session 中的值匹配,如果不匹配则永远驱逐该用户。

这显然是假设您使用启用了视图状态的传统 asp.net。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我认为没有简单的方法。

    您可以使用 javascript 并尝试各种 http 浏览器缓存设置,但您不能真正依赖其中的任何一个。您必须假设用户将能够重新发布表单。

    我认为您在服务器代码中处理它是正确的。这个怎么样:

    在网格页面的 GET 中创建一个 cookie/会话变量。 在网格页面的 POST 中使该 cookie/会话变量无效。

    这样,当通过后退按钮重新发布时,您的代码应该检测到没有有效的 cookie/会话值,然后可以重新发出重定向到同一页面,强制执行 GET。

    PRG 模式。

    当您提到回发中的“结果页面”时,听起来您已经在使用 Post-Redirect-Get 模式。如果您不是,那么这有助于解决用户在已发布表单上按 F5 的其他问题。

    祝你好运!

    【讨论】:

      【解决方案3】:

      GridView 中异步删除记录怎么样? (使用更新面板)

      这将阻止浏览器将选中的复选框保存在浏览器缓存中,并消除每当用户在完整回发后刷新页面时烦人的安全弹出浏览器检查。

      或者,您是否尝试过在第一次绑定后取消选中代码隐藏中的所有复选框? (比如说在 Page_Load 上)

      试试这个:

      <asp:UpdatePanel id="upGv" runat="server" ChildrenAsTriggers="false" UpdateMode="Conditional">
          <ContentTemplate>
              <asp:GridView ID="gv" runat="server" />
              <asp:Button ID="btnDelete" runat="server" Text="Delete" />
          </ContentTemplate>
      </asp:UpdatePanel>
      

      在代码隐藏中:

      Private Sub btnDelete_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDelete.Click
          ' do a for loop searching for selected checkboxes and do the deleting here
          ' --- delete codes ---
          ' rebind the data in gridview
          gv.DataSource = 'some dataset/datatable etc etc
          gv.DataBind()
          'update the updatepanel
          upGv.Update()
      End Sub
      

      【讨论】:

      • 我有同样的想法,但我认为你不能在可重复的控件中触发异步回发......可能是生成的 id 的问题。异步仍然是解决方案,但是您必须将其包装在一堆 JS 下:获取所有选中的项目,提取 Id,将它们传递给 Web 服务,更新更新面板
      • @Steve B - 回发将由网格下方的删除按钮触发,而不是由网格本身触发 - updatepanel 是一个可行的解决方案。问题是,OP 是否希望增加与使用 MS Ajax 库和部分回发相关的复杂性、噪音和页面重量?
      • 你是对的,它不是嵌套在gridview中的控件,而是外部的控件......这应该不是问题^-^。你的话是对的...... Ajax 不附带阿司匹林
      猜你喜欢
      • 1970-01-01
      • 2013-03-02
      • 1970-01-01
      • 2011-02-17
      • 1970-01-01
      • 2016-02-20
      • 1970-01-01
      • 2017-06-29
      • 2013-01-10
      相关资源
      最近更新 更多