我有一个ASP.NET MVC 3应用程序,它有一个名为Create
的帖子操作:
[HttpPost]
public virtual ActionResult Create(Issues issues)
{
if (ModelState.IsValid)
{
context.Issues.Add(issues);
context.SaveChanges();
return RedirectToAction("Index");
}
return View(issues);
}
如果我错误地双击提交按钮,则会产生2x问题。有没有办法防止这种情况,没有使用javascript和禁用按钮,我认为使用RedirectToAction
的全部用途是通过使用Post / Redirect / Get设计模式来阻止这种情况?
答案 0 :(得分:6)
简单的解决方案!
单击时禁用提交按钮。 结束。
$('submitButtonId').click(function(){
$(this).prop('disabled', true);
$(this).attr('disabled', 'disabled'); // for jQuery versions < 1.6.
});
答案 1 :(得分:4)
您提到的模式(发布/重定向/获取设计模式)会阻止页面刷新双重发布,因为最后一个操作是GET,而不是POST。
如果您想阻止双重发布的双击,您可以:
1. Disable the button after click 2. Maintain a unique index on 'Issues' and look for duplicates 3. Maintain something in session that gives you an indication of a double post
还有一些方法......我认为禁用按钮可能是最简单的,因为你无论如何都要重定向到另一个页面。
答案 2 :(得分:2)
我能想到的最简单的方法是使用Session:
if (ModelState.IsValid)
{
DateTime now = DateTime.Now;
if (Session["LastAdd"] == null || (now - (DateTime)Session["LastAdd"]).TotalMilliseconds > 1000)
{
//first time, or more than a second passed since last addition
context.Issues.Add(issues);
context.SaveChanges();
Session["LastAdd"] = now;
}
return RedirectToAction("Index");
}
答案 3 :(得分:1)
您可以在向用户显示表单时生成IssueId,然后检查您在Create方法中是否已经存在此类ID的问题,例如,跳过此类请求。
答案 4 :(得分:0)
PRG模式不会阻止这种情况,因为其中的P动作需要时间(通常是这种情况),并且用户可以再次提交表单(通过点击或浏览器刷新),这将导致PRG模式为& #34;失败&#34 ;.
请注意,恶意用户也可以通过快速连续运行多个http帖子来绕过所有客户端测量。
上述所有方法的解决方案是使用以下方法检查服务器端的重复提交,如我自己所描述的here。
为方便起见,我引述:
&#34;如果您在表单中使用隐藏的防伪标记(就像您一样) 应该),你可以在第一次提交时缓存防伪标记 如果需要,从缓存中删除令牌,或使缓存的条目到期 经过一段时间后。
然后,您将能够针对缓存检查每个请求 具体表格是否已提交,如果有,则拒绝。&#34;