【发布时间】:2009-04-13 10:43:36
【问题描述】:
我有一个应用程序,我在其中添加一条新记录,如果我按下刷新按钮,记录会被添加两次。
我正在清除缓存,但我遇到了同样的问题。 怎么办?
【问题讨论】:
-
没有足够的信息来帮助你
-
这个问题过去肯定被问过很多次,但我很难找到其他问题。我已经改写了标题,以便将来可以找到这个问题。我希望安妮和社区不要介意。
标签: asp.net
我有一个应用程序,我在其中添加一条新记录,如果我按下刷新按钮,记录会被添加两次。
我正在清除缓存,但我遇到了同样的问题。 怎么办?
【问题讨论】:
标签: asp.net
一旦您处理了返回页面的帖子,最佳做法是随后重定向,这样您就无法使用“刷新”按钮再次发布数据。这对所有 Web 开发都很常见,而不仅仅是 ASP.NET。
【讨论】:
我的方法被无耻地从this ASP Alliance 上的精彩文章的第 4 页窃取。要检测刷新,您可以在 ViewState 和 Session 中存储相同的值。如果用户刷新页面,它将使用与您的 Session 值不匹配的旧 ViewState 数据进行 PostBack。一旦检测到这一点,您就可以使用一个简单的变量创建一个所有其他 Page 都继承自的 Page,以测试用户是否刷新了浏览器。此解决方案需要启用 ViewState 和有效的 Session。
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (IsPostBack && ViewState[REFRESH_CHECK_GUID] != Session[REFRESH_CHECK_GUID])
{
IsRefresh = true;
}
Session[REFRESH_CHECK_GUID] = System.Guid.NewGuid().ToString();
ViewState[REFRESH_CHECK_GUID] = Session[REFRESH_CHECK_GUID];
}
/// <summary>
/// True if the last PostBack was caused by a Page refresh.
/// </summary>
public virtual bool IsRefresh
{
get;
private set;
}
【讨论】:
在理想情况下,导致数据库更新的 HTTP POST 提交将在成功更新后重定向到通知用户操作成功的辅助页面。如果用户试图返回上一个页面,浏览器会提示用户类似“”如果不重新发送信息,页面将无法刷新。单击“重试”重新发送信息或单击“取消”继续“。这足以说明用户刷新页面将导致重复提交。但是,如果更新失败,将加载同一页面并允许用户重试。
当然,这不是一成不变的规则,实施方式各不相同。我强烈建议您将 @edg 的建议付诸实践 - 您的数据库插入代码应始终在应用插入/更新之前检查重复性。
【讨论】:
如果您没有任何会话(并且启用了 cookie),您可以使用:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (IsPostBack && ViewState[REFRESH_CHECK_GUID] != Request.Cookies[REFRESH_CHECK_GUID])
{
IsRefresh = true;
}
String checkGuid=System.Guid.NewGuid().ToString();
Response.Cookies[REFRESH_CHECK_GUID] = checkGuid;
ViewState[REFRESH_CHECK_GUID] = checkGuid;
}
/// <summary>
/// True if the last PostBack was caused by a Page refresh.
/// </summary>
public virtual bool IsRefresh
{
get;
private set;
}
【讨论】:
如果应用程序是您的,您需要添加代码,在尝试将记录保存到数据库之前先检查该记录是否不存在。
【讨论】:
问题是由于位于 __EVENTTARGET 中的隐藏值无法通过代码设置。
如果您可以使用 Ajax 添加数据,则可以解决此问题。
【讨论】:
即使我们对整个表单使用 Ajax,它也会提供相同的重复插入, 但我们可以尝试通过清除 hiddenfield _EventTaret 并更改其他一些控件的焦点:)
【讨论】:
正如 David M 上面所说,最好的办法是在发布后重定向。另一个服务器往返的影响非常小,因为只有 http 标头在重定向中发送。
【讨论】:
如果您需要留在同一页面,那么我建议您将用户重定向到确认页面,然后您可以询问用户是否要插入另一条记录,如果是,那么您将它们重定向回可以插入记录的页面,这将有助于防止重复插入。或者,如果他们完成插入记录,他们可以直接进入“主”页面。当我需要用户在插入后能够“停留”在同一页面中时,这就是我过去所做的。
【讨论】:
插入或更新语句执行后,您可以将用户重定向到同一页面
Response.Redirect(Request.Url.AbsoluteUri);
【讨论】: