日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

Asp.net MVC中防止HttpPost重复提交

發布時間:2024/9/20 c/c++ 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Asp.net MVC中防止HttpPost重复提交 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

重復提交的場景很常見,可能是當時服務器延遲的原因,如購物車物品疊加,重復提交多個訂單。常見的解決方法是提交后把Button在客戶端Js禁用,或是用Js禁止后退鍵等。在ASP.NET MVC 3?Web Application中 如何去防止這類HTTP-Post的重復提交呢? 我們可以借助Session,放置一個Token在View/Page上,然后在Server端去驗證是不是同一個Token來判斷此次Http-Post是否有效。看下面的代碼:? 首先定義一個接口,便于擴展。

public interface IPageTokenView {/// <summary>/// Generates the page token./// </summary>string GeneratePageToken();/// <summary>/// Gets the get last page token from Form/// </summary>string GetLastPageToken { get; }/// <summary>/// Gets a value indicating whether [tokens match]./// </summary>/// <value>/// <c>true</c> if [tokens match]; otherwise, <c>false</c>./// </value>bool TokensMatch { get; } }


定義一個Abstract Class,包含一個

public abstract class PageTokenViewBase : IPageTokenView {public static readonly string HiddenTokenName = "hiddenToken";public static readonly string SessionMyToken = "Token";/// <summary>/// Generates the page token./// </summary>/// <returns></returns>public abstract string GeneratePageToken();/// <summary>/// Gets the get last page token from Form/// </summary>public abstract string GetLastPageToken { get; }/// <summary>/// Gets a value indicating whether [tokens match]./// </summary>/// <value>/// <c>true</c> if [tokens match]; otherwise, <c>false</c>./// </value>public abstract bool TokensMatch { get; }}


接著是實現SessionPageTokenView類型,記得需要在驗證通過后生成新的Token,對于這個Class是把它放到Session中。

public class SessionPageTokenView : PageTokenViewBase{#region PageTokenViewBase/// <summary>/// Generates the page token./// </summary>/// <returns></returns>public override string GeneratePageToken(){if (HttpContext.Current.Session[SessionMyToken] != null){return HttpContext.Current.Session[SessionMyToken].ToString();}else{var token = GenerateHashToken();HttpContext.Current.Session[SessionMyToken] = token;return token;}}/// <summary>/// Gets the get last page token from Form/// </summary>public override string GetLastPageToken{get{return HttpContext.Current.Request.Params[HiddenTokenName];}}/// <summary>/// Gets a value indicating whether [tokens match]./// </summary>/// <value>/// <c>true</c> if [tokens match]; otherwise, <c>false</c>./// </value>public override bool TokensMatch{get{string formToken = GetLastPageToken;if (formToken != null){if (formToken.Equals(GeneratePageToken())){//Refresh tokenHttpContext.Current.Session[SessionMyToken] = GenerateHashToken();return true;}}return false;}}#endregion #region Private Help Method/// <summary>/// Generates the hash token./// </summary>/// <returns></returns>private string GenerateHashToken(){return Utility.Encrypt(HttpContext.Current.Session.SessionID + DateTime.Now.Ticks.ToString());} #endregion

這里有到一個簡單的加密方法,你可以實現自己的加密方法.?

public static string Encrypt(string plaintext) {string cl1 = plaintext;string pwd = string.Empty;MD5 md5 = MD5.Create();byte[] s = md5.ComputeHash(Encoding.Unicode.GetBytes(cl1));for (int i = 0; i < s.Length; i++){pwd = pwd + s[i].ToString("X");}return pwd; }

我們再來編寫一個Attribute繼承FilterAttribute, 實現IAuthorizationFilter接口。然后比較Form中Token與Session中是否一致,不一致就Throw Exception. Tips:這里最好使用依賴注入IPageTokenView類型,增加Logging 等機制?

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public sealed class ValidateReHttpPostTokenAttribute : FilterAttribute, IAuthorizationFilter {public IPageTokenView PageTokenView { get; set; }/// <summary>/// Initializes a new instance of the <see cref="ValidateReHttpPostTokenAttribute"/> class./// </summary>public ValidateReHttpPostTokenAttribute(){//It would be better use DI inject it.PageTokenView = new SessionPageTokenView();}/// <summary>/// Called when authorization is required./// </summary>/// <param name="filterContext">The filter context.</param>public void OnAuthorization(AuthorizationContext filterContext){if (filterContext == null){throw new ArgumentNullException("filterContext");}if (!PageTokenView.TokensMatch){//log...throw new Exception("Invaild Http Post!");}} }


還需要一個HtmlHelper的擴展方法:

public static HtmlString GenerateVerficationToken(this HtmlHelper htmlhelper) {string formValue = Utility.Encrypt(HttpContext.Current.Session.SessionID+DateTime.Now.Ticks.ToString());HttpContext.Current.Session[PageTokenViewBase.SessionMyToken] = formValue;string fieldName = PageTokenViewBase.HiddenTokenName;TagBuilder builder = new TagBuilder("input");builder.Attributes["type"] = "hidden";builder.Attributes["name"] = fieldName;builder.Attributes["value"] = formValue;return new HtmlString(builder.ToString(TagRenderMode.SelfClosing)); }


將輸出這類的HtmlString:?

<input name="hiddenToken" type="hidden" value="1AB01826F590A1829E65CBD23CCE8D53" />

我們創建一個叫_ViewToken.cshtml的Partial View,這樣便于模塊化,讓我們輕易加入到具體View里,就兩行代碼,第一行是擴展方法NameSpace

@using Mvc3App.Models; @Html.GenerateVerficationToken()

假設我們這里有一個簡單的Login.cshtml,然后插入其中:
<form method="post" id="form1" action="@Url.Action("Index")"><p>@Html.Partial("_ViewToken")UserName:<input type="text" id="fusername" name="fusername" /><br />Password:<input type="password" id="fpassword" name="fpassword" /><input type="submit" value="Sign-in" /></p></form>
這里我們Post的Index Action,看Controller代碼,我們在Index上加上ValidateReHttpPostToken的attribute.


[HttpPost] [ValidateReHttpPostToken] public ActionResult Index(FormCollection formCollection) {return View(); }public ActionResult Login() {return View(); }

好的,完了,由于篇幅有限,單元測試代碼不貼了。讓我們運行程序在IE中. 正常點擊Button后提交表單,此時按F5再次提交,看到這個提示框:



點擊Retry后,這時就會出現預期Exception,這里只是為了演示,實際中可能需要記錄日志,做異常處理。

Invaild Http Post!

Description:?An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.?Exception Details:?System.Exception: Invaild Http Post!?
有興趣您可以自己試一下,希望對您Web開發有幫助。

總結

以上是生活随笔為你收集整理的Asp.net MVC中防止HttpPost重复提交的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产精品视频一区二区在线观看 | 国产精品一区二区免费看 | 欧美日韩一区二区区别是什么 | 亚洲欧美视频在线播放 | 国产精彩视频在线 | ass日本粉嫩pics珍品 | 超碰婷婷 | 国产精品一区二区在线观看 | np视频| 亚洲最大av网 | 青青草视频成人 | 天天干夜夜草 | 97成人在线观看 | 热热色原网址 | www色网站| 中文有码在线播放 | 国产精品视频999 | 日本妈妈9 | 日本在线视频www色 国产在线视频网址 | 91精品国产日韩91久久久久久 | 成人午夜精品福利免费 | 特级毛片网站 | 国产真实乱人偷精品视频 | 风间由美在线观看 | 一级a性色生活片久久无 | 国产精品一区二区三区免费在线观看 | 最近最新中文字幕 | 麻豆久久久久 | 国产精品xxx在线观看www | 少妇人妻互换不带套 | 国产青青草视频 | 在线看a网站 | 制服丝袜手机在线 | 久99精品 | 国产精品扒开腿做爽爽爽视频 | 杨幂一区二区三区免费看视频 | 欧美性猛交xxxxx水多 | 少妇高潮a一级 | 狠狠狠 | 最新自拍偷拍 | 韩国视频一区二区 | 又爽又黄视频 | 亚洲无限av | 三级av免费 | 男人天堂国产 | 色人阁五月 | 一本久 | 久久久久久久久久久久久国产 | 久久久久久亚洲av无码专区 | 欧美在线三区 | 女人的av| 国产亚洲精久久久久久无码77777 | 亚洲一级网站 | 欧美性受xxx黑人xyx性爽 | 青青草手机视频在线观看 | 国产农村妇女毛片精品久久麻豆 | 青久草视频| 无码人妻一区二区三区在线 | 污污网站在线观看 | 色一五月 | 国产三区精品 | 成人日韩视频 | 欧美视频亚洲视频 | 一级全黄色片 | 性高湖久久久久久久久aaaaa | 国产免费黄色av | www.浪潮av.com | 另类小说五月天 | 久久a久久 | 99自拍视频| 五月的婷婷| 91视频啊啊啊 | 日韩av无码久久 | 国产精品综合视频 | 欧美日韩一级二级 | 999国产 | 色欧美综合| 精品成人av一区二区在线播放 | 免费性网站 | 中文字幕国产一区 | 91老师国产黑色丝袜在线 | 夜色一区 | 伊人久久一区二区三区 | 亚洲一区二区精品视频 | 天天色天天色 | 欧美性受xxxx黑人xyx性爽 | 国产在线一区不卡 | 毛片啪啪啪 | 日本高清网站 | 欧美性网址 | 日本激情网址 | 国产一区二区色 | 日日夜夜av| 韩日中文字幕 | 黄色片aaaa | 欧美日韩高清免费 | 一区二区精品在线 | 天堂va欧美va亚洲va老司机 | 欧美一级免费黄色片 |