利用Action Filter 防止重复提交

1、原文:http://15815850410.blog.163.com/blog/static/11499607920135742231644/
 1  public class NoResubmitAttribute : ActionFilterAttribute
 2     {
 3         private static readonly string HttpMehotdPost = "POST";
 4         private static readonly string prefix = "postFlag";
 5         private string nameWithRoute;
 6 
 7         public override void OnActionExecuting(ActionExecutingContext filterContext)
 8         {
 9             var controllerContext = filterContext.Controller.ControllerContext;
10             if (!controllerContext.IsChildAction)
11             {
12                 var request = controllerContext.HttpContext.Request;
13                 var session = controllerContext.HttpContext.Session;
14                 nameWithRoute = generateNameWithRoute(controllerContext);
15                 int sessionFlag = session[nameWithRoute] == null ? 0 : (int)session[nameWithRoute];
16                 int requestFlag = string.IsNullOrEmpty(request.Form[nameWithRoute]) ? 0 : int.Parse(request.Form[nameWithRoute]);
17                 // get or normal post: true;    
18                 bool isValid = !IsPost(filterContext) || sessionFlag == requestFlag;
19                 if (sessionFlag == int.MaxValue)
20                 {
21                     sessionFlag = -1;
22                 }
23                 session[nameWithRoute] = ++sessionFlag;
24                 if (!isValid)
25                 {
26                     filterContext.Result = new RedirectResult(GenerateUrlWithTimeStamp(request.RawUrl));
27                     return;
28                 }
29             }
30             base.OnActionExecuting(filterContext);
31         }
32 
33         private string GenerateUrlWithTimeStamp(string url)
34         {
35             return string.Format("{0}{1}timeStamp={2}", url, url.Contains("?") ? "&" : "?", (DateTime.Now - DateTime.Parse("2010/01/01")).Ticks);
36         }
37 
38         private bool IsPost(ActionExecutingContext filterContext)
39         {
40             return filterContext.HttpContext.Request.HttpMethod == HttpMehotdPost;
41         }
42 
43         private string generateNameWithRoute(ControllerContext controllerContext)
44         {
45             StringBuilder sb = new StringBuilder(prefix);
46             foreach (object routeValue in controllerContext.RouteData.Values.Values)
47             {
48                 sb.AppendFormat("_{0}", routeValue);
49             }
50             return sb.ToString();
51         }
52 
53         public override void OnResultExecuted(ResultExecutedContext filterContext)
54         {
55             base.OnResultExecuted(filterContext);
56             if (!filterContext.IsChildAction && !(filterContext.Result is RedirectResult))
57             {
58                 //string format = "<script type='text/javascript'>$(function () [[ $('form').each(function()[[$('<input type=hidden id={0} name={0} value={1} />').appendTo($(this));]])]]); </script>";
59                 string format = "<script type='text/javascript'> var forms = document.getElementsByTagName('form'); for(var i = 0; i<forms.length; i++)[[var ele = document.createElement('input'); ele.type='hidden'; ele.id=ele.name='{0}'; ele.value='{1}'; forms[i].appendChild(ele);]] </script>";
60                 string script = string.Format(format, nameWithRoute, filterContext.HttpContext.Session[nameWithRoute]).Replace("[[", "{").Replace("]]", "}");
61                 filterContext.HttpContext.Response.Write(script);
62             }
63         }
64     }
65 
66 
67 
68         [HttpGet]
69         [NoResubmit]
70         public ActionResult Index()
71         {
72             return View();
73         }
74 
75         [HttpPost]
76         [NoResubmit]
77         public ActionResult Index(int id)
78         {
79             return View();
80         }
81 
82         [NoResubmit]
83         public ActionResult About()
84         {
85             return View();
86         }        
View Code
2、原文:http://www.kuiyu.net/art-15.html
 1 public class PreventSpamAttribute : ActionFilterAttribute
 2 {
 3       //处理请求之间的延迟
 4       public int DelayRequest = 10;
 5       //防止多次请求时的错误提示信息
 6       public string ErrorMessage = "Excessive Request Attempts Detected.";
 7       //出错时URL重定向
 8       public string RedirectURL;
 9 
10       public override void OnActionExecuting(ActionExecutingContext filterContext)
11       {
12              base.OnActionExecuting(filterContext);
13       }
14 }
View Code
 1 public override void  OnActionExecuting(ActionExecutingContext filterContext)
 2 {
 3       //存储 HttpContext 
 4       var request = filterContext.HttpContext.Request;
 5 
 6       //获取IP请求者的IP地址
 7       var originationInfo = request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? request.UserHostAddress;
 8 
 9       //Append the User Agent
10       originationInfo += request.UserAgent;
11 
12       //目标URL信息
13       var targetInfo = request.RawUrl + request.QueryString;
14 
15       base.OnActionExecuting(filterContext);
16 }
View Code
 1 public override void  OnActionExecuting(ActionExecutingContext filterContext)
 2 {
 3       //Store our HttpContext 
 4       var request = filterContext.HttpContext.Request;
 5       //Store our HttpContext.Cache 
 6       var cache = filterContext.HttpContext.Cache;
 7 
 8       //Grab the IP Address from the originating Request 
 9       var originationInfo = request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? request.UserHostAddress;
10 
11       //Append the User Agent
12       originationInfo += request.UserAgent;
13 
14       //目标URL信息
15       var targetInfo = request.RawUrl + request.QueryString;
16 
17       //创建希哈值
18       var hashValue = string.Join("", MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(originationInfo + targetInfo)).Select(s => s.ToString("x2")));
19 
20       //如果希哈值在缓存中,(重复提交)
21       if (cache[hashValue] != null)
22       {
23               //添加错误信息
24               filterContext.Controller.ViewData.ModelState.AddModelError("ExcessiveRequests", ErrorMessage);
25       }
26       else
27       {
28               //使用希哈值的key添加一个空对象到缓存中(决定是否过期)
29               //if the Request is valid or not
30               cache.Add(hashValue, hashValue, null, DateTime.Now.AddSeconds(DelayRequest), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
31       }
32       base.OnActionExecuting(filterContext);
33 }
View Code
 1 应用
 2 //Displays your form initially
 3 public ActionResult YourPage()
 4 {
 5       return View(new TestModel());
 6 }
 7 
 8 [HttpPost]
 9 [PreventSpam]
10 public ActionResult YourPage(TestModel yourModel)
11 {
12       //If your Model was valid - output that it was successful!
13       if (ModelState.IsValid)
14       {
15              return Content("Success!");
16       }
17       //Otherwise return the model to the View
18       else
19       {
20              return View(yourModel);
21       }
22 }
23 
24 
25 //This action can only be accessed every 60 seconds and any additional requests within that timespan will 
26 //notify the user with a custom message. 
27 [PreventSpam(DelayRequest=60,ErrorMessage="You can only create a new widget every 60 seconds.")]
28 public ActionResult YourActionName(YourModel model)
29 {
30       //Your Code Here
31 }  
View Code

还可以用 使用Post/Redirect/Get实现Asp.net防止表单重复提交 就是Http-Post完后,马上做Redirect操作,接下来那个页面是Get。这时用户强制按F5刷新也没有用了。

原文:http://www.cnblogs.com/wintersun/archive/2012/03/24/2415349.html

原文地址:https://www.cnblogs.com/tider1999/p/4058303.html