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

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

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

時(shí)間:2015-06-28 00:00:00 來(lái)源:IT貓撲網(wǎng) 作者:網(wǎng)管聯(lián)盟 我要評(píng)論(0)

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

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

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

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

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

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

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

1、繼承 System.Web.UI.Page,自訂一個(gè) BasePage 類(lèi)別。

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

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

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

3、處理?PreRender 事件,在網(wǎng)頁(yè)初次載入時(shí)設(shè)置戳記,且每次載入執(zhí)行時(shí)會(huì)把該戳記存放到 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)頁(yè)是否經(jīng)由重新整理動(dòng)作回傳。

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

    相關(guān)閱讀

    文章評(píng)論
    發(fā)表評(píng)論

    熱門(mén)文章 誅仙3飛升任務(wù)怎么做-誅仙3飛升任務(wù)流程最新2022 誅仙3飛升任務(wù)怎么做-誅仙3飛升任務(wù)流程最新2022 鐘離圣遺物推薦-原神鐘離圣遺物詞條 鐘離圣遺物推薦-原神鐘離圣遺物詞條 解決方法:應(yīng)用程序“DEFAULT WEB SITE”中的服務(wù)器錯(cuò)誤 解決方法:應(yīng)用程序“DEFAULT WEB SITE”中的服務(wù)器錯(cuò)誤 使用aspnet_regiis.exe 重新注冊(cè).NET Framework 使用aspnet_regiis.exe 重新注冊(cè).NET Framework

    相關(guān)下載

      人氣排行 誅仙3飛升任務(wù)怎么做-誅仙3飛升任務(wù)流程最新2022 asp.net表單提交方法GET\POST 在A(yíng)SP.NET中如何判斷用戶(hù)IE瀏覽器的版本 Asp.net中messagebox的實(shí)現(xiàn)方法 Asp.net中的web.config配置 在A(yíng)SP.NET MVC中實(shí)現(xiàn)大文件異步上傳 asp.net獲取URL和IP地址 FileUpload上傳多文件出現(xiàn)錯(cuò)誤的解決方法

      <track id="xeyhr"><tbody id="xeyhr"></tbody></track>
      <p id="xeyhr"><tr id="xeyhr"></tr></p>
          <small id="xeyhr"><dl id="xeyhr"></dl></small>