mvc 防止客服端多次提交
但凡web开发中都会有户多次点击了提交按钮导致多次提交的情况,一般的集中做法
1、通过js在用户点击的时候将按钮disabled掉,但是这样并不是很可靠(我就可以跳过这个,用一个for循环 我直接自己post数据过去)
2、在生成客服端html的时候存放一个隐藏的input,input里面存放一个随机生成的值(一般为guid),服务器端会将此值保存,等用户提交的时候 判断提交过来的guid是否匹配(这种方法相对第一种安全性更高,但是如果是全静态的页面的话就不满足了,于是自己琢磨了第3中解决方案)
3、通过自定义ActionFilter来实现,代码如下
public class PreventMutipleSubmitAttribute:ActionFilterAttribute { private int delaySecond =5; /// <summary> /// 重复提交的时间秒(两次间隔不大于改值时视为重复提交),默认为5s /// </summary> public int DelaySecond { get { return delaySecond; } set { delaySecond = value; } } public override void OnActionExecuting(ActionExecutingContext filterContext) { var request=filterContext.RequestContext.HttpContext.Request; var cache = filterContext.RequestContext.HttpContext.Cache; var paramModel = filterContext.ActionParameters; paramModel.Add("userID", ApplicationPrincipal.CurrentPrincipal.UserID); paramModel.Add("userIP", request.UserHostAddress); var clientPostModel = JsonConvert.SerializeObject(paramModel); var md5Model = MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(clientPostModel)).Select(s => s.ToString("x2")); var hashValue = string.Join("", md5Model); if (cache[hashValue] == null) { cache.Add(hashValue, "", null, DateTime.Now.AddSeconds(delaySecond), Cache.NoSlidingExpiration, CacheItemPriority.Default, null); base.OnActionExecuting(filterContext); } else { filterContext.Result = new MutipleSubmitException(); } } }
跟权限过滤器一样,在需要防止多次提交的地方打上这个标签就ok啦。
解释下实现的思路:主要是将用户提交过来的参数+用户IP+用户主键ID 然后得到这些值的md5,将得到的md5值存放在缓存中(只存了5秒,根据实际情况可以适当增加),当用户提交过来的时候判断缓存中是否与这个键,如果有就是重复提交的,在else里面做相应的处理就可以了,我这里的MutipleSubmitException是自定义的一个异常状态码,你也可以自己定义返回json什么的都可以,配合前端的处理就跟完美了。ok 到此,服务器端防止多次提交完毕!如有bug谢谢网友反馈...