一: 开题
这篇只是一个简单的应用技巧,高手请跳过,别拍砖,打击我这个有激情的菜鸟。在我们的web项目中经常会遇见由于网络原为等问题,而导致在页面提高后,服务器还没有来得及返回的时候,我们的用户可能在此点击按钮使的数据多次的提交。防止这个行为很简单,我们一般经常是在按钮点击后使其禁用disabled=true。我是一个很懒的人(生活中并不懒,只是写Code比较懒,我的目标是:少写Code,基于配置而不写Code是最好的)。所以就有了这个简单的辅助类:我的思路是在page的PreRender时间中注册提交前执行的脚本全部提交按钮的disabled=true( page.ClientScript.RegisterOnSubmitStatement()。)等待服务器返回时会更具返回浏览器会重绘,所以我们的设置此时已经无用了。呵呵就这面简单。但是为不少写代码,那些了一个辅助类DoubleSubmitPrevent,提供的几种方式自动按照按钮,或者是手动添加按钮(取决于IsAutoFind),自动查找的起点默认为page,但是为了效率你可以自己设置BaseContrlForFind,关于需要禁止的按钮的判断为IsPreventControl你可以自己定义覆盖默认的,默认为:
代码 private System.Predicate < System.Web.UI.Control > isPreventControl = t => (t is System.Web.UI.WebControls.Button) || (t is System.Web.UI.WebControls.LinkButton) || (t is System.Web.UI.WebControls.ImageButton) || (t is System.Web.UI.HtmlControls.HtmlButton) || // (t is System.Web.UI.HtmlControls.HtmlLink) || (t is System.Web.UI.HtmlControls.HtmlInputButton) || (t is System.Web.UI.HtmlControls.HtmlInputSubmit);
如果你还是觉得效率不好那么,你就可以自己Add或者AddRange,同时包括了Remove,Insert等方法,这一系列方法都支持链式操作(这是第一次使用jQuery的时候给我的最大触动)。例如:dsp.Add(Button1).Add(Button2).Add(Button3).Add(LinkButton1).Add(LinkButton2) =dsp.AddRange(Button1,Button2,Button3,LinkButton1,LinkButton2);包括的多个重载;
二: Code部分
说了这么多还是直接上代码:
namespace Wolf.Utils { public class DoubleSubmitPrevent { private System.Collections.Generic.List < string > _clientIDList = null ; private const string DOUBLE_SUBMIT_PREVENT_STR = " B3F6F682-F404-4519-9F30-79876E5A5C9A_WOLF_DOUBLESUBMITPREVENT_391B8D4F-757E-4005-8262-062652D8BAC6 " ; private bool isAutoFind = false ; #region judje Prevent Control? private System.Predicate < System.Web.UI.Control > isPreventControl = t => (t is System.Web.UI.WebControls.Button) || (t is System.Web.UI.WebControls.LinkButton) || (t is System.Web.UI.WebControls.ImageButton) || (t is System.Web.UI.HtmlControls.HtmlButton) || // (t is System.Web.UI.HtmlControls.HtmlLink) || (t is System.Web.UI.HtmlControls.HtmlInputButton) || (t is System.Web.UI.HtmlControls.HtmlInputSubmit); #endregion private System.Web.UI.Control baseContrlForFind = null ; /// <summary> /// Auto Find will satrt with this Control;Default this Page . /// </summary> public System.Web.UI.Control BaseContrlForFind { get { return baseContrlForFind; } set { baseContrlForFind = value; } } /// <summary> /// judje the Contrl that be prevented; /// </summary> public System.Predicate < System.Web.UI.Control > IsPreventControl { get { return isPreventControl; } set { isPreventControl = value; } } /// <summary> /// Auto Find the Control that be prevented ? /// </summary> public bool IsAutoFind { get { return isAutoFind; } set { isAutoFind = value; } } public DoubleSubmitPrevent(System.Web.UI.Page page) { _clientIDList = new System.Collections.Generic.List < string > (); baseContrlForFind = page; page.PreRenderCompleted += new System.EventHandler(DoubleSubmitPreventPagePreRenderHick); } public DoubleSubmitPrevent Add( string clientID) { _clientIDList.Add(clientID); return this ; } public DoubleSubmitPrevent Add(System.Web.UI.Control ctr) { _clientIDList.Add(ctr.ClientID); return this ; } public DoubleSubmitPrevent AddRange( params string [] clientIDs) { _clientIDList.AddRange(clientIDs); return this ; } public DoubleSubmitPrevent AddRange( params System.Web.UI.Control[] ctrs) { foreach (var item in ctrs) { Add(item); } return this ; } public DoubleSubmitPrevent Remove( string clientID) { _clientIDList.Remove(clientID); return this ; } public DoubleSubmitPrevent Remove(System.Web.UI.Control ctr) { _clientIDList.Remove(ctr.ClientID); return this ; } public bool Exists( string clientID) { return _clientIDList.Exists(t => t.Equals(clientID)); } public bool Exists(System.Web.UI.Control ctr) { return _clientIDList.Exists(t => t.Equals(ctr.ClientID)); } protected virtual void DoubleSubmitPreventPagePreRenderHick( object sender, System.EventArgs e) { System.Web.UI.Page page = sender as System.Web.UI.Page; if (page != null ) { if (isAutoFind) { #region Find Action System.Action < System.Collections.Generic.List < string > , System.Web.UI.Control > action = null ; action = (list, ctr) => { if (ctr != null ) { if (isPreventControl(ctr)) { list.Add(ctr.ClientID); } foreach (System.Web.UI.Control item in ctr.Controls) { action(list, item); } } }; #endregion action(_clientIDList, baseContrlForFind); } System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (var item in _clientIDList) { sb.Append( string .Format( " document.getElementById(\ " { 0 }\ " ).disabled=true; " , item)); } page.ClientScript.RegisterOnSubmitStatement( this .GetType(), DOUBLE_SUBMIT_PREVENT_STR, sb.ToString()); } } } } 三: 测试:
为了模拟延时,我在后台加了睡眠:
代码 protected void Page_Load( object sender, EventArgs e) { if (IsPostBack) { System.Threading.Thread.Sleep( 1000 * 5 ); TextBox1.Text = DateTime.Now.ToString(); Button3.Enabled = false ; } Wolf.Utils.DoubleSubmitPrevent dsp = new Wolf.Utils.DoubleSubmitPrevent( this ) { IsAutoFind = true , BaseContrlForFind = this .form1 }; // dsp.Add(Button1).Add(Button2).Add(Button3).Add(LinkButton1).Add(LinkButton2); } 前台html(乱托乱扔的,看来是比较懒):
代码 < form id = " form1 " runat = " server " > < asp:TextBox ID = " TextBox1 " runat = " server " ></ asp:TextBox > < asp:Button ID = " Button1 " runat = " server " Text = " Button " Enabled = " false " /> < asp:Button ID = " Button2 " runat = " server " Text = " Button " /> < asp:Button ID = " Button3 " runat = " server " Text = " Button " /> < asp:LinkButton ID = " LinkButton1 " runat = " server " > LinkButton </ asp:LinkButton >< asp:LinkButton ID = " LinkButton2 " runat = " server " > LinkButton </ asp:LinkButton > </ form > 效果:
如果你又更好的方案,也希望能给我分享,请大家多多指教。
作者:
出处:
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-、和。http://www.cnblogs.com/whitewolf/archive/2010/11/19/1881991.html