防止双重提交

时间:2012-03-21 11:02:36

标签: c# jquery asp.net-mvc asp.net-mvc-3

我有一个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设计模式来阻止这种情况?

5 个答案:

答案 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;