IT貓撲網(wǎng):您身邊最放心的安全下載站! 最新更新|軟件分類|軟件專題|手機版|論壇轉(zhuǎn)貼|軟件發(fā)布

您當前所在位置:首頁網(wǎng)絡(luò)編程.Net編程 → ASP.NET 如何避免頁面重新整理時重復(fù)送出

ASP.NET 如何避免頁面重新整理時重復(fù)送出

時間:2015/6/28來源:IT貓撲網(wǎng)作者:網(wǎng)管聯(lián)盟我要評論(0)

有些使用者的行為真是令人猜不透…,開網(wǎng)頁有事沒事就來給你 Refresh 一下,這個動作看似無害,但是在剛執(zhí)行過 Submit 的情況下,Refresh 網(wǎng)頁會造成重復(fù)執(zhí)行,這也是為什么在各大購物網(wǎng)站的交易付款動作,都會提示「不要關(guān)閉網(wǎng)頁或重新整理避免造成交易失敗或重復(fù)交易」這一類的訊息,但根據(jù)經(jīng)驗,就算在網(wǎng)頁上提出警告了,仍有為數(shù)不少的使用者依然會 Refresh 網(wǎng)頁。

注意,別以為只有 ASP.NET 才有這種問題,這問題普遍存在于網(wǎng)頁程式,不管你用何種平臺、語言開發(fā),這肇因于瀏覽器會自行 Cache 使用者的瀏覽行為 (包含資料),測試過 IE、FireFox、chrome 都一樣,猜想是因為這樣才能有上一頁、下一頁的歷程紀錄,至于更進一步的探討,小的力有未逮就不再深究 (歡迎瞭解的前輩高人指點一下迷津,說說緣由)…既然瀏覽器塬始設(shè)計如此,而我們可能永遠都猜不透使用者愛怎么操作,那就針對 ASP.NET 的開發(fā)來看看有甚么方式可以解決這樣的問題。

不知道有沒有人跟我一樣,馬上想到的是:重新導(dǎo)向,也就是在執(zhí)行某一工作成功之后,執(zhí)行 Response.Redirect 方法重導(dǎo)到結(jié)果頁面,這是最典型的作法,不過這比較適用在動作連貫的多重網(wǎng)頁表單,例如:購物車,在完成結(jié)帳后就可以導(dǎo)到訂購成功的訊息頁面,反正前面也從第一步、第二步…到結(jié)帳畫面了,再多導(dǎo)一次已經(jīng)差別不大?上Ф嘀鼐W(wǎng)頁表單畢竟是少數(shù),大部分網(wǎng)頁程式現(xiàn)在幾乎都要求非同步更新 (AJAX),最好在同一畫面完成所有動作,即便今天不要求非同步更新,每個作業(yè)完成之后都導(dǎo)到另一個網(wǎng)頁,也不甚理想,所以這種作法并不完美,除了多維護一個網(wǎng)頁的麻煩不說,事實上使用者若先回到上一頁再重新整理,一樣可能會造成重復(fù)執(zhí)行…。

那在任何異動前,先檢查是否有相同資料存在呢?換句話說是在資料庫端檢查,應(yīng)該可行,不過…過程似乎稍嫌繁瑣,要針對每一個作業(yè)內(nèi)容個別去撰寫比對是否有相同資料的邏輯,光想就覺得累了…,況且有時候確實是可以允許相同資料存在,比如說線上客服的留言版,使用者不耐久候時,會再留言一次,內(nèi)容可能跟前次一模一樣,這跟重刷頁面造成的資料重復(fù)是不可相提并論的,這樣看來在資料庫端排除相同資料也不是很好的作法…

關(guān)鍵點在于怎么分辨出使用者正在重刷頁面,進一步地,有沒有一勞永逸的做法,讓我們可以檢查某一屬性就能判斷是不是重刷頁面所回傳,來避免重復(fù)送出動作?轉(zhuǎn)念一想:太陽底下無新事,上網(wǎng)搜尋了一下,國外有幾篇文章、討論串針對這問題提出了幾個解法 (事實證明前述兩種作法也是有人建議),其中我覺得最值得一看的是底下兩篇:

Build Your ASP.NET Pages on a Richer Bedrock Preventing Duplicate Record Insertion on Page Refresh

參考上列兩篇文章的內(nèi)容,得到最后的答案是:我們可以繼承 ASP.NET 的 Page 類別,自行擴充所需的功能!作法如下:

1、繼承 System.Web.UI.Page,自訂一個 BasePage 類別。

以下為引用的內(nèi)容:
  1. using System;   
  2.   
  3. /// <summary>   
  4. /// BasePage 的摘要描述   
  5. /// </summary>   
  6. public class BasePage : System.Web.UI.Page   
  7. {   
  8.     public BasePage() { }   
  9. }  

2、在 BasePage 類別底下撰寫 SetActionStamp 方法,目的是在 Session 存放一個系統(tǒng)時間戳記。

以下為引用的內(nèi)容:
  1. /// <summary>   
  2. /// 設(shè)置戳記   
  3. /// </summary>   
  4. private void SetActionStamp()   
  5. {   
  6.     Session["actionStamp"] = Server.UrlEncode(DateTime.Now.ToString());   
  7. }  

3、處理 PreRender 事件,在網(wǎng)頁初次載入時設(shè)置戳記,且每次載入執(zhí)行時會把該戳記存放到 HiddenField 里。

以下為引用的內(nèi)容:
  1. public BasePage() { this.PreRender += new EventHandler(Page_PreRender); }   
  2.   
  3. void Page_PreRender(object sender, EventArgs e)   
  4. {   
  5.     if (!IsPostBack)   
  6.     {   
  7.   SetActionStamp();   
  8.     }   
  9.   
  10.     ClientScript.RegisterHiddenField("actionStamp", Session["actionStamp"].ToString());   
  11. }  

4、自訂 IsRefresh 屬性,藉由判斷 HiddenField 存放的戳記是否等于 Session 裡存放的值,就可以得知網(wǎng)頁是否經(jīng)由重新整理動作回傳。

以下為引用的內(nèi)容:
  1. 關(guān)鍵詞標簽:ASP.NET

    相關(guān)閱讀

    文章評論
    發(fā)表評論

    熱門文章 手把手教你用好LINQ to SQL手把手教你用好LINQ to SQL在.NET環(huán)境下為網(wǎng)站增加IP過濾功能在.NET環(huán)境下為網(wǎng)站增加IP過濾功能ASP.NET 如何避免頁面重新整理時重復(fù)送出ASP.NET 如何避免頁面重新整理時重復(fù)送出用Asp.net擴展ExtJS用Asp.net擴展ExtJS

    相關(guān)下載

    人氣排行 asp.net表單提交方法GET\POST在ASP.NET中如何判斷用戶IE瀏覽器的版本Asp.net中messagebox的實現(xiàn)方法Asp.net中的web.config配置在ASP.NET MVC中實現(xiàn)大文件異步上傳用Iformattable接口控制.Net中文本格式c#.Net經(jīng)典面試題目用Asp.net擴展ExtJS