熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

一步步打造防止重復提交按鈕

2013-11-13 10:31:52  來源: .NET編程 
    首先說說防止重復提交按鈕是啥東西
    我們在訪問有的網站輸入表單完成以後單擊提交按鈕進行提交以後提交按鈕就會變為灰色用戶不能再單擊第二次直到重新加載頁面或者跳轉這樣可以一定程度上防止用戶重復提交導致應用程序上邏輯錯誤有朋友說這個按鈕完全可以用js來做是的不過當你需要大量這種按鈕時是否為每一個都去編程而不封裝一個呢?
    另外為了增加其功能性我們除了讓他有防止重復提交的功能以外還可以給他彈出提示框就像單擊刪除按鈕時用戶會受到一個提示再次確認是否真的刪除
    好接下來第一步知識儲備
    我們知道要防止重復提交要在客戶端設法使用戶單擊一次以後按鈕變灰這種客戶端行為顯然只能借助js代碼來完成服務器端運行的ASPNET是做不到的那要讓客戶端用戶單擊按鈕後立即收到一條再次確認消息在確認之前不會提交到服務器也需要js代碼因此我們基本的絲路就是在頁面加載按鈕時一並把所需的js代碼發送到客戶端去而該按鈕都是適用js腳本因此不影響服務器端行為
    第二步從Button繼承
    因為它是一個按鈕擁有按鈕所需要的全部特征屬性因此我們就從SystemWebUIWebControlsButton這個類繼承而防止重復提交按鈕在按鈕變成灰色以後應該顯示什麼文本呢?新增一個AfterSubmitText屬性來指示采用一個Bool值ShowMessageBox屬性來確定是否需要在客戶端彈出提示使用WarningText屬性來指示客戶端彈出提示的內容
    第三步
    現在我們就來改寫AddAttributesToRender方法ASPNET在渲染該控件到輸出時會調用該方法我們所改寫的方法以達到將JS代碼發送到客戶端的目的具體代碼如下
    protected override void AddAttributesToRender(HtmlTextWriter writer)
    {
    SystemTextStringBuilder ClientSideEventReference = new SystemTextStringBuilder()
    if (((thisPage != null) && thisCausesValidation) && (thisPageValidatorsCount > ))
    {
    ClientSideEventReferenceAppend(if (typeof(Page_ClientValidate) == function){if (Page_ClientValidate() == false){return false;}}
    }
    //ShowMessageBox?
    if (thisShowMessageBox)
    {
    ClientSideEventReferenceAppend(if (!confirm( + thisWarningText + )){return false}
    }
    ClientSideEventReferenceAppendFormat(thisvalue = {}; (string)thisViewState[afterSubmitText])
    ClientSideEventReferenceAppend(thisdisabled = true;
    ClientSideEventReferenceAppend(thisPageClientScriptGetPostBackEventReference(this stringEmpty))
    writerAddAttribute(HtmlTextWriterAttributeOnclick ClientSideEventReferenceToString() true)
    baseAddAttributesToRender(writer)
    }
    我們把發送到客戶端的js代碼看作是一個字符串為了提高性能用StringBuilder來對象來構造這個字符串
    首先根據頁面對象存在且控件啟用了驗證(該屬性從父繼承)且頁面對象的驗證器內計數大於來決定輸出一段引發驗證的js代碼
    根據ShowMessageBox屬性來決定輸出一個彈出提示的代碼並且彈出提示的內容由WarningText屬性給出
    書寫一個js腳本為按鈕賦值為提交後文本並且將按鈕設置為禁用以變灰色
    最後附加一段由ASPNET提供的用於影射回調事件引用的js腳本(thisPageClientScriptGetPostBackEventReference(this stringEmpty)方法將返回一個回送事件引用的js腳本字符串)
    將StringBuilder對象內構造的字符串用HtmlTextWriter對象的AddAttribute方法寫入按鈕的OnClick事件中
    調用父類的AddAttributesToRender方法讓父類有機會完成其他的配置等操作
    完整的ClickOnceButton代碼如下
    using System;
    using SystemCollectionsGeneric;
    using SystemComponentModel;
    using SystemText;
    using SystemWeb;
    using SystemWebUI;
    using SystemWebUIWebControls;
    namespace BlogLanWebControls
    {
    /// <summary>
    /// 表示一個防止重復提交的按鈕當用戶單擊按鈕以後該按鈕變灰不能再次單擊直到重新加載頁面或者跳轉
    /// </summary>
    [DefaultProperty(Text)]
    [ToolboxData(<{}:ClickOnceButton runat=server></{}:ClickOnceButton>)]
    public class ClickOnceButton : SystemWebUIWebControlsButton
    {
    /// <summary>
    /// 默認的構造函數
    /// </summary>
    public ClickOnceButton()
    {
    thisViewState[afterSubmitText] = 正在提交請稍候…;
    baseText = ClickOnceButton;
    thisViewState[showMessageBox] = false;
    thisViewState[warningText] = 確定要提交嗎?;
    }
    /// <summary>
    /// 獲取或設置單擊按鈕後按鈕上所顯示的文本
    /// </summary>
    [Bindable(true)
    Category(Appearance
    DefaultValue(正在提交請稍候…
    Description(指示單擊提交後按鈕上所顯示的文本)]
    public string AfterSubmitText
    {
    get
    {
    string afterSubmitText = (string)thisViewState[afterSubmitText];
    if (afterSubmitText != null)
    {
    return afterSubmitText;
    }
    else
    {
    return stringEmpty;
    }
    }
    set
    {
    thisViewState[afterSubmitText] = value;
    }
    }
    [Bindable(true)
    Category(Appearance
    DefaultValue(false)
    Description(指示是否要顯示一個提示框)]
    public bool ShowMessageBox
    {
    get
    {
    return (bool)thisViewState[showMessageBox];
    }
    set
    {
    thisViewState[showMessageBox] = value;
    }
    }
    [Bindable(true)
    Category(Appearance
    DefaultValue(確定要提交嗎?
    Description(指示提示框內所包含的內容)]
    public string WarningText
    {
    get
    {
    return (string)thisViewState[warningText];
    }
    set
    {
    thisViewState[warningText] = value;
    }
    }
    /// <summary>
    /// AddAttributesToRender
    /// </summary>
    /// <param name=writer>HtmlTextWriter</param>
    protected override void AddAttributesToRender(HtmlTextWriter writer)
    {
    SystemTextStringBuilder ClientSideEventReference = new SystemTextStringBuilder()
    if (((thisPage != null) && thisCausesValidation) && (thisPageValidatorsCount > ))
    {
    ClientSideEventReferenceAppend(if (typeof(Page_ClientValidate) == function){if (Page_ClientValidate() == false){return false;}}
    }
    //ShowMessageBox?
    if (thisShowMessageBox)
    {
    ClientSideEventReferenceAppend(if (!confirm( + thisWarningText + )){return false}
    }
    ClientSideEventReferenceAppendFormat(thisvalue = {}; (string)thisViewState[afterSubmitText])
    ClientSideEventReferenceAppend(thisdisabled = true;
    ClientSideEventReferenceAppend(thisPageClientScriptGetPostBackEventReference(this stringEmpty))
    writerAddAttribute(HtmlTextWriterAttributeOnclick ClientSideEventReferenceToString() true)
    baseAddAttributesToRender(writer)
    }
    }
    }
    你可以把它編譯為dll放置在工具箱中隨意拖放到網頁上即可使用因為繼承了Button控件它擁有Button的全部特性並且自動繼承了Button的設計時支持
    後記
    當我決定自己開發自定義控件時這是我第一個想到的因為明確它就是在一個Button控件基礎上並用JS代碼來實現功能因此它應該是一個比較簡單的東西了
    代碼貼出來與各位分享盡管現在新技術層出不窮用AJAX也可以達到效果不過假如你只是想要防止重復提交也不用勞煩AJAX這個沉重的框架來完成有點殺雞用牛刀了
    願各位朋友舉一反三深入探討
From:http://tw.wingwit.com/Article/program/net/201311/13917.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.