防止重复提交验证机制
某些时候因为系统反应稍慢,急性子用户可能不耐烦会进行重复的提交,这个操作不仅可能造成系统负担,也可能产生垃圾数据。
出现这两种状况都是我们不希望的。
为此,在公司项目系统设计了以下防止反复提交机制,用来避免这种状况。
工作原理
使用MVC Action拦截器,在用户提交信息时记录提交时间,并用此时间和上次提交时间对比,如果这个时间小于一定的时间差,则不允许重复提交,异常提示类似:
图:不允许反复提交的异常
拦截器代码:
/// <summary> /// 防止重复提交过滤器 /// </summary> /// <remarks> /// 跟踪的顺序 /// OnActionExecuting /// OnActionExecuted /// OnResultExecuting /// OnResultExecuted /// </remarks> public class DisabledReSubmitActionAttribute : ActionFilterAttribute { // 不允许重复提交时间间隔 private int m_ReSubmitSeconds = 2; /// <summary> /// 构建方法 /// </summary> /// <param name="reSubmitSeconds">不允许重复提交的时间间隔:秒</param> public DisabledReSubmitActionAttribute(int reSubmitSeconds) { m_ReSubmitSeconds = reSubmitSeconds; } /// <summary> /// 在controller action执行之前调用 /// </summary> /// <param name="filterContext">controller action内容</param> public override void OnActionExecuting(ActionExecutingContext filterContext) { var session = filterContext.HttpContext.Session; //第一次加载 if (session["lastSubmitTime"] == null) { session["lastSubmitTime"] = DateTime.Now.AddSeconds(-100); } //计算当前时间和上次提交的时间差 TimeSpan ts = DateTime.Now - (DateTime)session["lastSubmitTime"]; //n 秒内不允许重复提交 if (ts.TotalSeconds < m_ReSubmitSeconds) { // 抛出重复提交异常 throw new AppExReSubmit(m_ReSubmitSeconds); } else { //更新保存的时间值 session["lastSubmitTime"] = DateTime.Now; // 继续执行Action base.OnActionExecuting(filterContext); } } }
使用方式(示例)
使用该拦截器只要在提交处理的Action方法上声明该过滤器属性即可,其中参数5表示5秒内不可以重复提交,见以下代码红色字体。
[DisabledReSubmitAction(5)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ReSubmitTest(FormCollection collection)
{
ViewData["Message"] = "方式:POST" + DateTime.Now.ToString();
return View();
}