Asp.net防止刷新重提交数据库操作
最近在写个B/S的应用系统,采用Asp.net(2..0)+Windows验证+Ajax+Sql2005+VS2008+Windows2003的组合。
由于我们对的是公司内部客户(两个财务部的小姑娘),做了几个输入界面就叫她们测试。
发现新增数据或修改数据后刷新浏览器系统会重复前一次(最近一次的数据库操作)。
这里将解决这个问题的解决方案和大家分享一下啊。
我的思路是:
上BaiDu上google上搜搜,但几种解决方案都不适合我的情况。
网上的方案有:
1、数据库操作后跳转回本页。
即数据操作成功后:this.Page.Response.Redirect = "本页的URL";
这个方案是可以防止刷新重提交数据库操作,但被财务的小姑娘否定了,原因是跳转到本页分页总是默认跳到第一页的,这样他看
不到刚刚输入的数据,要看的话还要翻到最后一页.
2、用ViewState做标记
提交后,ViewState["IsSubmit"]=false;
这个根本不行的,因为ViewState["IsSubmit"]是利用HiddenField实现的,本身刷新时提交的数据是前一次的数据,因此
ViewState["IsSubmit"]也是前一次的值.
3、用Session来做开关,这个也不行的,还是没办法判断人家是刷新还是重新提交的啊。
没办法,以上办法都行不通的情况下,只有自己想解决方案。
我的想法是:
1、既然你是提交前次的数据,为我就要做下标记(要唯一的),但记录的值本身不能作为标记,因为完全有可能插入或修改一样的记录
。
2、最后我决定我用一个HiddenField(ID为IsSubmit)记住这个标识.产生这个唯一值的方法是:
//IsSubmit
<asp:HiddenField ID="IsSubmit" runat="server" Value="0" />
//插入
<asp:Button ID="Button1" runat="server" CausesValidation="True"
CommandName="Insert" Text="插入" OnClientClick="javaScript:document.getElementById
('IsSubmit').value=(new Date()).getTime()" />
//更新
<asp:Button ID="Button1" runat="server" CausesValidation="True"
CommandName="Update" Text="更新" OnClientClick="javaScript:document.getElementById
('IsSubmit').value=(new Date()).getTime()"/>
说明下,上面作用是当插入和更新把HiddenField(ID为IsSubmit)的值赋值为系统当前的毫秒数(应该没办法在以毫秒内又提交又刷新
吧,而且这个值对一个Session理论上是永远唯一的啊).
3、看我服务器端的动作(插入)
protected void SqlDataSource3_Inserting(object sender, SqlDataSourceCommandEventArgs e)
{
if ("" + this.Session["LastSubmitID"] == "")
{
this.Session.Add("LastSubmitID", this.IsSubmit.Value);//如果这个Session不存在说明以前没提交过,肯定不是重复的,放行
,但要把this.IsSubmit.Value记载到this.Session["LastSubmitID"]中,以备下次比较
}
else
{
if ("" + this.Session["LastSubmitID"] == "" + this.IsSubmit.Value)//如果存在this.Session["LastSubmitID"]且与
this.IsSubmit.Value相等则说明是刷新的,因为刷新时是提交的上次的数据,this.IsSubmit.Value值当然也不会变,跳过数据操作
{
e.Cancel=true;
}
else//如果存在this.Session["LastSubmitID"]但与this.IsSubmit.Value不相等,说明是通过点击了插入或更新的数据操作,为正
常操作,放行,但要把这次的this.IsSubmit.Value记载到this.Session["LastSubmitID"]中,以备下次比较
{
this.Session["LastSubmitID"] = "" + this.IsSubmit.Value;
}
}
}
更新就不解释了,同理的
protected void SqlDataSource3_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
if ("" + this.Session["LastSubmitID"] == "")
{
this.Session.Add("LastSubmitID", this.IsSubmit.Value);
}
else
{
if ("" + this.Session["LastSubmitID"] == "" + this.IsSubmit.Value)
{
e.Cancel=true;
}
else
{
this.Session["LastSubmitID"] = "" + this.IsSubmit.Value;
}
}
}
4、肯定又同志说了,每个数据库操作都要插入这样一大堆代码,太烦了啊.我们可以把验证是否正常提交写成一个方法来调用就不用这么
烦了啊.
如:
private bool CheckLastSubmitID()//验证是否正常提交
{
if ("" + this.Session["LastSubmitID"] == "")
{
this.Session.Add("LastSubmitID", this.IsSubmit.Value);
return true;
}
if ("" + this.Session["LastSubmitID"] == "" + this.IsSubmit.Value)
{
return false;
}
else
{
this.Session["LastSubmitID"] = "" + this.IsSubmit.Value;
return true;
}
}
上面的两个事件的代码换成:
protected void SqlDataSource3_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
if(!CheckLastSubmitID())
{
e.Cancel=true;
}
}
protected void SqlDataSource3_Inserting(object sender, SqlDataSourceCommandEventArgs e)
{
if(!CheckLastSubmitID())
{
e.Cancel=true;
}
}
不烦了吧,哈哈。
水平有限,写的不好,请诸位博友见谅了啊。