一种利用异常机制基于MVC过滤器的防止重复提交的机制分享

防止重复提交验证机制

某些时候因为系统反应稍慢,急性子用户可能不耐烦会进行重复的提交,这个操作不仅可能造成系统负担,也可能产生垃圾数据。

出现这两种状况都是我们不希望的。

为此,在公司项目系统设计了以下防止反复提交机制,用来避免这种状况。

工作原理

使用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();

    }

posted @ 2013-06-20 17:12  拓荒之客  阅读(699)  评论(0编辑  收藏  举报