最近在网上查了好久,基本上都是 Html 按钮:<input id="btnSubmit" type="button" value="提交" language="javascript" onclick="return Button1_onclick()" />而在 .NET 开发中,服务端按钮的使用越来越频繁,很难用 JavaScript 等客户端脚本防止重复提交:<asp:Button ID="btnSubmit" runat="server" Text="提交" OnClick="btnSubmit_Click" />protected void btnSubmit_Click(object sender, EventArgs e)
{...}
防止重复提交的方法:1、在数据库中使记录不能完全相同。
缺点1:为了让最近插入的数据容易降序排列,通常使用 ID 字段为主键,并设置自动编号,这样就没有完全相同的记录了。
缺点2:插入之前先判断除 ID 字段外,是否有相同的记录,如果有,则不插入;这样每插入一条记录都需要多一步查询,大大的浪费服务器资源。2、设置一个Session,在 Page_Load 的(!IsPostBack) 条件中赋值“未单击”;在 btn_Click 事件中,先判断是否为“未单击”,如果是,则提交,然后将 Session 中的值设置为“已提交”。
缺点1:如果 已经单击了一次提交按钮,Session 值就变成“已提交”了,当客户端再次点击时,就会被 btn_Click 中的判断所拦截,拦截之后应当如何处理呢?
a.直接 return ,可以有效避免重复提交;但是这样就无法转向“提交成功,请等待自动跳转”页面了,用户也就不知道是否真的已经提交上去,同时也不能利用跳转页防后退了。
b.直接跳转到“提交成功,请等待自动跳转”页面,这样只要用户单击两次按钮,就会跳转到此页,给用户带来迷惑;
而且这种方法,有可能在第一次单击没有提交完成,就触发第二次单击,导致数据提交不上去,但是又显示“提交成功,请等待自动跳转”。
缺点2:如果用户打开此页面,无意中单击了一次提交按钮;用户并不知道,从而继续填写表单,当表单填写完成,再次单击提交按钮时,导致数据提交不上去。
可以使用验证控件禁止文本框为空,避免客户无意中就单击了按钮;但是如果一个页面存在多个按钮,就不能使用该控件了。
防重复提交问题是老问题,也是棘手问题,很多人都在寻找比较完善的解决方案。
请大家畅所欲言。
{...}
防止重复提交的方法:1、在数据库中使记录不能完全相同。
缺点1:为了让最近插入的数据容易降序排列,通常使用 ID 字段为主键,并设置自动编号,这样就没有完全相同的记录了。
缺点2:插入之前先判断除 ID 字段外,是否有相同的记录,如果有,则不插入;这样每插入一条记录都需要多一步查询,大大的浪费服务器资源。2、设置一个Session,在 Page_Load 的(!IsPostBack) 条件中赋值“未单击”;在 btn_Click 事件中,先判断是否为“未单击”,如果是,则提交,然后将 Session 中的值设置为“已提交”。
缺点1:如果 已经单击了一次提交按钮,Session 值就变成“已提交”了,当客户端再次点击时,就会被 btn_Click 中的判断所拦截,拦截之后应当如何处理呢?
a.直接 return ,可以有效避免重复提交;但是这样就无法转向“提交成功,请等待自动跳转”页面了,用户也就不知道是否真的已经提交上去,同时也不能利用跳转页防后退了。
b.直接跳转到“提交成功,请等待自动跳转”页面,这样只要用户单击两次按钮,就会跳转到此页,给用户带来迷惑;
而且这种方法,有可能在第一次单击没有提交完成,就触发第二次单击,导致数据提交不上去,但是又显示“提交成功,请等待自动跳转”。
缺点2:如果用户打开此页面,无意中单击了一次提交按钮;用户并不知道,从而继续填写表单,当表单填写完成,再次单击提交按钮时,导致数据提交不上去。
可以使用验证控件禁止文本框为空,避免客户无意中就单击了按钮;但是如果一个页面存在多个按钮,就不能使用该控件了。
防重复提交问题是老问题,也是棘手问题,很多人都在寻找比较完善的解决方案。
请大家畅所欲言。
public class Button : System.Web.UI.WebControls.Button
{
int second = 0;
[Category("控制台"), Browsable(true), Bindable(false), Description("自动启用的时间")]
public int Second
{
get
{
return second;
}
set
{
second = value;
}
}
string format = "({0})";
[Category("控制台"), Browsable(true), Bindable(false), Description("格式")]
public string Format
{
get
{
return format;
}
set
{
format = value;
}
}
string confirm = "";
[Category("控制台"),DefaultValue(""), Browsable(true), Bindable(false), Description("确认按钮")]
public string Confirm
{
get
{
return confirm;
}
set
{
confirm = value;
}
}
protected override void Render(HtmlTextWriter writer)
{
this.UseSubmitBehavior = false;//使用客户端提交机制
//this.OnClientClick = "this.disabled='disabled';";
if (this.CausesValidation)
{
this.CausesValidation = false;
this.OnClientClick += "if (typeof(Page_ClientValidate) == 'function') if(!Page_ClientValidate()){return false;}";
}
if (string.IsNullOrEmpty(Confirm))
{
this.OnClientClick += "this.disabled='disabled';";
}
else
{
this.OnClientClick += "if(!confirm('" + Confirm + "')){return false;}this.disabled='disabled';";//点击以后按钮灰色,防止多次点击
}
if (Second>0)
{
this.Attributes["disabled"]="disabled";
this.Text = this.Text + string.Format(Format, Second);
string script = @"
var Button_I="+Second.ToString()+ @";
var Button_X;
var Button_Format='"+Format+ @"';
function ButtonRefresh()
{
if(Button_I==0)
{
document.getElementById('" + this.ClientID+ @"').disabled='';
var temp=document.getElementById('" + this.ClientID + @"').value;
temp=temp.replace(Button_Format.replace('{0}',Button_I),'');
document.getElementById('" + this.ClientID + @"').value=temp;
window.clearInterval(Button_X);
}
else
{
document.getElementById('" + this.ClientID + @"').disabled='disabled';
var temp=document.getElementById('" + this.ClientID + @"').value;
temp=temp.replace(Button_Format.replace('{0}',Button_I),Button_Format.replace('{0}',Button_I=Button_I-1));
document.getElementById('" + this.ClientID + @"').value=temp;
}
}
function window.onload()
{
Button_X=window.setInterval('ButtonRefresh()',1000);
}
";
this.Page.ClientScript.RegisterStartupScript(this.GetType(), "Button", script, true);
}
base.Render(writer);
}
}
解决方法一: .Framework2.0中才有的button属性:<asp:button id="btnSubmit" onclick="btnSubmit_Click" runat="server" OnClientClick="this.disabled=true;this.form.submit();" UseSubmitBehavior="False" /> 解决重复提交:OnClientClick="this.disabled=true;this.form.submit();" UseSubmitBehavior="False"解决方法二: this.btnSubmit.Attributes["onclick"] = this.GetPostBackEventReference(this.btnSubmit) + ";this.disabled=true;"; //防止重复提交
我试过,似乎不管用...
在后台设置,网速慢,传不到客户端就被单击多次了;
在前台设置,这种按钮又不行,需要js,而js又是在客户端的,安全性、可靠性都不让人放心。
服务器端的控制,对于这种问题,有点大牛拉小车的感觉不过有些情况下,还是要用的我的做法是
在录入页页,做一个随机数,存入Session同时存入隐藏的表单元素里
提交后在服务器端检查,相同则放行,否则提示错误信息,然后立即清除session
对,如果写在存储过程中,效率也会提高,而且只需调用一次;如果写在后台代码中,则需要访问多次数据库。
但是写在存储过程中,灵活性差。
比如数据库中的 表名 不确定时,就不能用存储过程,只能用后台代码来拼接SQL语句了。
请问有代码段吗?
如果在 Load_Page 中生成随机数,它就会在单击提交按钮后 Click 事件之前 自动再执行一次 Load_Page ,Session 中的随机数就更改了啊。
one: function( type, data, fn ) {
return this.each(function(){
jQuery.event.add( this, type, function(event) {
jQuery(this).unbind(event);
return (fn || data).apply( this, arguments);
}, fn && data);
});
}
<script type="text/javascript">
$(document).ready(function(){
$("p").one("click",function(){
alert($(this).text());//这里放你要处理的
});
});
</script>
$.one()
使用JQurey中的one函数可以轻松实现该功能
1. 完全用js写。
2. 前台js和后台代码并合成写。具体方法:js+ajax
我用的是第二种。
如果是VS里面的标准控件(非html控件),就很难用前台代码控制。
如果在后台控制Textbox清空,就需要等服务器的清空回传到客户机,才能实现清空,网速慢的话还未等到回传回来就已经单击好几次了。
{...}请问这种按钮如何使用 JS?
public void page_load(Object obj,EventArgs e)
...{
btn.Attributes.Add("onclick","state=true;");
StringBuilder sb=new StringBuilder();
sb.Append("if (!state) return;");
sb.Append("var button=document.getElementById('btn');");
sb.Append("button.value=" Please Wait... ";");
sb.Append("document.body.style.cursor='wait';");
sb.Append("button.disabled=true;"); string strScript="<script>";
strScript=strScript +"var state=false;"; //将函数绑定到页面的onbeforeunload事件:
strScript=strScript +"window.attachEvent('onbeforeunload',function(){" +sb.ToString()+ "});";
strScript=strScript +"</"+"script>";
Page.RegisterStartupScript("onbeforeunload",strScript);
} private void Submit_Click(Object sender, EventArgs e)
...{
//模拟长时间的按钮处理
System.Threading.Thread.Sleep(2000);
Response.Write("<script>alert('bbbbbb!!');"+"</"+"script>"); } <asp:button id="btn" Text="Submit" OnClick="Submit_Click" runat="server"/>你可以直接参考我的文章看怎么解决的:http://blog.csdn.net/lfywy/archive/2008/05/23/2475372.aspx
{
btnSubmit.Visiable=false;或btnSubmit.Disable=true;
}
论坛提交帖子可以,因为帖子输入好多字才需要输入一次验证码,
但web应用程序就不行了,容易引起反感。OnClientClick 好像管用,目前没有那么慢的网速条件,无法一试。
<asp:Button ID="btnSubmit" runat="server" Text="累加" OnClientClick="this.disabled=true;this.form.submit();" UseSubmitBehavior="False" OnClick="btnSubmit_Click" /><br />
protected void btnSubmit_Click(object sender, EventArgs e)
{
lbl.Text = Convert.ToString(Convert.ToInt32(lbl.Text) + 1);
}
这是错误的,客户端按钮可以通过return false禁止提交,那asp.net自带的控件按钮当然也可以。
这是没有什么区别的,不知道楼主担心何在。
是这样:一个表单页,一个防后退跳转页(上面写着“提交成功,自动返回”);
表单提交成功后,会自动转至跳转页,然后自动跳回。
如果用 return 禁止提交,就不能跳到跳转页显示“提交成功,自动返回”了,用户并不知道实际上已经提交成功了。
ajax来写
把后退按钮都给屏蔽了
using System;
using System.Collections.Generic;
using System.Text;
/**/
/// <summary>
/// 名称:SubmitOncePage
/// 父类:System.Web.UI.Page
/// 描述:解决浏览器刷新造成的数据重复提交问题的page扩展类。
/// 示例: if (!this.IsRefreshed)
/// {
/// //具体代码
/// }
/// 原创:丛兴滋(cncxz) E-mail:[email protected]
/// </summary>
namespace SPA.Common
{
public class SubmitOncePage : System.Web.UI.Page
{
private string _strSessionKey;
private string _hiddenfieldName;
private string _strLastViewstate;
public SubmitOncePage()
{
_hiddenfieldName = "__LastVIEWSTATE_SessionKey";
_strSessionKey = System.Guid.NewGuid().ToString();
_strLastViewstate = string.Empty; } public bool IsRefreshed
{
get
{
string str1 = this.Request.Form["__VIEWSTATE"];
_strLastViewstate = str1;
string str2 = this.Session[GetSessinKey()] as string;
bool flag1 = (str1 != null) && (str2 != null) && (str1 == str2);
return flag1;
}
} protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
string str = GetSessinKey();
this.Session[str] = _strLastViewstate;
this.RegisterHiddenField(_hiddenfieldName, str);
base.Render(writer);
}
private string GetSessinKey()
{
string str = this.Request.Form[_hiddenfieldName];
return (str == null) ? _strSessionKey : str;
}
}}
下面代码是调用上面的IsRefreshed属性 但是事先要继承 SubmitOncePage 类namespace SPA.Web
{
public partial class Default1 : SPA.Common.SubmitOncePage
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button4_Click(object sender, EventArgs e)
{
int i = int.Parse(Label2.Text) + 1;
Label2.Text = i.ToString();
if (!this.IsRefreshed)
{
WriteFile("a.txt", i.ToString());
}
WriteFile("b.txt", i.ToString());
}
}
}
不知道是不是你要想的 如果不清楚可加我QQ38789461
下面是我写的针对LinkButton防止重复提交:UploadFileSubmit.Attributes.Add("onclick", "return checkSubmitCount();");
UploadFileSubmit.Attributes.Add("href", "javascript:" + "submitCount++;" + Page.ClientScript.GetPostBackEventReference(UploadFileSubmit, "Click"));System.Text.StringBuilder sb = new StringBuilder();
sb.Append("<script>");
sb.Append("var submitCount = 0;\n");
sb.Append("function checkSubmitCount() {");
sb.Append(" if(submitCount==0)");
sb.Append(" return true;");
sb.Append(" return false;");
sb.Append("}");
sb.Append("\n\n");
sb.Append("</script>");
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "preventMultipleSubmit", sb.ToString());