在我的ASP.NET MVC应用程序的日志检查期间,我发现有些用户设法两次发布相同的表单。我试图重现它,但我失败了。无论如何,我想阻止用户两次发布相同的数据。在ASP.NET MVC中是否有任何规范的解决方案,或者我必须开发自己的自定义解决方案?
我的自定义解决方案我可以想象客户端和服务器端解决方案。在这两种情况下,你能推荐我什么吗?
答案 0 :(得分:8)
通常的方法是在点击后立即禁用提交按钮。
使用jQuery这样的东西应该可以工作:
<script type="text/javascript">
$("#myform").submit(function()
{ $("#submit-button").attr("disabled", "disabled"); });
</script>
现在仔细阅读你的问题并看到你使用ASP.NET MVC ......
双重帖子可能是因为用户在发布后刷新页面而引起的。如果您只是从帖子操作中返回一个视图:
[AcceptVerbs (HttpVerbs.Pos)]
ActionResult ProcessUserPost ()
{
/*...*/
return View ();
}
然后浏览器将尝试通过执行相同的步骤来重新创建页面,这意味着再次提交记住的表单。有些浏览器会显示一条警告信息(FireFox),其他浏览器会静静地显示(看Opera)。为了避免这种情况,您需要确保用户获取的页面是GET请求而不是POST的结果。
基本上,您需要执行重定向而不是返回视图。这将指示浏览器再次获取页面。
[AcceptVerbs (HttpVerbs.Pos)]
ActionResult ProcessUserPost ()
{
/*...*/
return RedirectToAction ("DisplayTheForm");
}
这样刷新页面不会导致发送新的POST请求。
当然,这不会阻止用户点击后退按钮返回到表单页面再次提交。但是这种情况应该在你的业务逻辑中处理,检查同一个用户对你正在做的事情的同一订单的双重提交。
答案 1 :(得分:5)
我可以想到三种方法来解决这个问题。
答案 2 :(得分:3)
我用来阻止双重帖子的一种技术是使用随每个帖子而变化的服务器端和客户端密钥。它的工作原理如下:
生成一个唯一的(随机)密钥 服务器并将其放入 会话以及隐藏的字段。
当用户回复第一个时 时间比较隐藏的关键 字段到会话中的键, 如果匹配,则接受输入 然后更改或删除密钥 从会话和更新 隐藏的领域也是如此。
如果是用户 设法点击两次提交 第二篇文章将失败,因为 HTML中的隐藏字段将不会 更长时间匹配会话变量 直到页面刷新。
答案 3 :(得分:2)
先停用按钮。
这将阻止用户在浏览器等待服务器响应时提交表单两次。但你应该小心这个。当用户点击提交时,您必须首先验证您的表单(如果您使用客户端验证),并且当它有效时,我会使用此代码禁用按钮。
$(":submit, :button").attr("disabled", true);
在控制器中使用以下重定向操作结果之一
这将阻止用户在表单进行重新发送POST数据的过程后点击F5。这称为 POST-REDIRECT-GET 模式。
RedirectToAction();
RedirectToRoute();
Redirect(); // redirects to URL
修改强>
正如您在评论中所说,您的页面已经使用了P-R-G模式。在这种情况下,我确保实施第一步。