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