【问题标题】:C# - If user refreshes page after inserting a record, a duplicate record is created. How can I prevent this?C# - 如果用户在插入记录后刷新页面,则会创建重复记录。我怎样才能防止这种情况?
【发布时间】:2011-10-19 11:57:01
【问题描述】:

对于页面上存在的任何其他功能都是如此。我不希望回发之前发生的最后一个事件再次发生。

【问题讨论】:

  • 要获得更具体的答案,您需要提供代码...

标签: c# .net web-applications insert postback


【解决方案1】:

相信你应该看看PRG Pattern (Post/Redirect/Get)

Post/Redirect/Get (PRG) 是 Web 开发人员常用的设计模式 帮助避免某些重复的表单提交并允许用户代理 使用书签和刷新按钮更直观地表现

在 ASP.NET 中:

  1. POST - 单击提交按钮会导致 HTTP POST
  2. 重定向 + 获取 - HttpResponse.Redirect()

MSDN,Redirecting Users to Another Page

在服务器代码中,您可以通过调用 重定向方法。该方法向用户的浏览器发送一个命令 导致浏览器为目标页面发出 HTTP GET 命令。

关于 PRG 模式的一些重要说明:

!!! PRG 模式不能解决所有重复表单的情况 提交。 PRG 无法提交的一些已知的重复表单提交 解决方法是:

  • 如果网络用户返回网络表单并重新提交。
  • 如果 Web 用户在服务器响应加载之前多次单击提交按钮(可以通过使用 JavaScript 禁用 第一次点击后的按钮)。
  • 如果网络用户由于服务器延迟在初始提交完成之前刷新,导致重复的 HTTP POST 请求 某些用户代理。
  • 如果恶意 Web 用户不顾客户端保护措施和典型浏览器行为两次提交表单。

【讨论】:

  • 然而,Nonce 键始终可以解决 PR​​G-NOT-WORKING-SENARIOS 问题。 nonce 键是服务器生成的随机唯一 GUID(也保存在数据库中)并嵌入到表单中。当用户发布表单时,随机数键也会被发布。一旦 POST 进入服务器,服务器就会验证其数据库中是否存在 nonce 键。如果是,服务器从数据库中删除密钥并处理表单。因此,如果用户 POST 两次,则不会处理第二个 POST,因为在处理第一个 POST 后删除了 nonce 键。
【解决方案2】:

您应该了解 PRG(发布/重定向/获取)模式:

Post/Redirect/Get (PRG) 是 Web 开发人员常用的设计模式 帮助避免某些重复的表单提交并允许用户代理 更直观地使用书签和刷新按钮。

来源:http://en.wikipedia.org/wiki/Post/Redirect/Get

基本上,您希望在用户完成 POST 后通过 GET 请求进行重定向。

【讨论】:

  • 谢谢杰米。因此,据我所知,在 .Net webforms 的上下文中,实现这一目标的唯一方法是在我不执行的每个操作之后实现类似 Response.Redirect(Request.RawUrl) 的东西;不想重复......导致两次往返到服务器:(这很糟糕!但我想我必须这样做......
  • @Kronprinz :是的,你是对的,在我的回答中,你可以找到一个指向 MSDN 页面的链接,该页面准确地描述了这一点
【解决方案3】:

您可以在将记录插入数据库之前检查已经存在的条件。

在存储过程中你可以检查

如果不存在(从列名 ='test' 的表中选择 id) 开始 插入语句.. 结束

【讨论】:

  • 我无权访问数据库,我正在通过 SOAP 调用工作。
  • 然后你可以在视图状态中设置标志值,就像第一次当被激活然后设置 viewstate["isinserted"] = true 然后检查条件,比如只有在 viewstate["isinserted"]= false 时插入/跨度>
  • 好的,如果这对您有帮助,请告诉我。
【解决方案4】:

这是关于PRG。避免这种情况的简单方法是再次将用户重定向到同一页面:

页面:Update.aspx

void btnUpdate_click(object sender, EventArgs e){
    // do your update here
    Response.Redirect("Update.aspx");
}

这将在Resoinse 中创建一个redirect-header,浏览器将创建一个GET 请求到Update.aspx 页面。如果用户刷新页面,将发送GET。看:

  1. 用户提交表单:POST
  2. 服务器进行更新,返回重定向标头
  3. 浏览器接收response 作为重定向命令:REDIRECT
  4. 浏览器向服务器发送GET 请求同一页面:GET
  5. 浏览器收到由GET 回答的response
  6. 如果用户刷新页面:浏览器的最后一个命令是GET,因此不会再次触发submit

【讨论】:

  • 两次往返服务器:(我希望有更好的解决方案。这应该以某种方式内置到框架中:)
  • 在 PRG 中,您有一个 POSTREDIRECT 和一个 GET,这意味着您必须向服务器请求 2 次!您也可以搜索另一种模式以避免往返:D
【解决方案5】:

一种简单的方法是在用户单击按钮时使用 javascript 禁用该按钮。

当需要高安全性时,我用来避免刷新的一种方法是在会话中使用一个小的“令牌”。 假设我们在会话中放入了一个小的 32 位整数。

该页面将包含一个隐藏的输入,其中包含我们的小整数标记。 每次收到页面请求时,我们都会将该令牌加一,并且在此之前,我们会检查与请求中收到的令牌是否相等。

如果它们匹配,则不是刷新。 如果它们不匹配,则刷新。

这也将阻止尝试使用浏览器按钮执行返回和下一步操作。

当然,当令牌不匹配时,页面应该更改,否则您将再次遇到刷新问题。 它应该显示类似“嘿,刷新回来或不允许下一步,按此处继续”之类的内容。

为了提高安全性,您可以将该整数与一个常量值进行异或,例如依赖于会话中的某个其他常量值。

【讨论】:

    猜你喜欢
    • 2012-08-17
    • 2011-04-13
    • 2011-06-18
    • 2020-12-18
    • 1970-01-01
    • 2023-03-05
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多