设为首页 | 加入收藏

网站建设报价咨询,网站建设A套餐 网站建设报价咨询,网站建设B套餐 网站建设报价咨询,网站建设C套餐 网站建设报价咨询
网站建设知识
网络整合营销外包,长沙网站建设
您目前的位置:森达网络 >>网站建设知识
网站建设知识

长沙专业做网站公司如何防止asp.net页面重复提交

本文来源: asp.net防止页面重复提交      本文作者:asp.net防止页面重复提交      发布时间:2017-09-14


 
长沙做网站在处理页面事件时,我们会经常会碰到这样的情况:当我们在提交一项页面表单时,在提交成功后,当我们试图按F5刷新页面时,数据会再次的被重复提交。浏览器的刷新是指重复上一次向服务器发送的请求,而asp.net的服务器控件的事件都是通过postback机制向服务器发送请求的。所以,当你点击提交按钮后再刷新,实际上是把提交按钮的postback请求又发送了一次。而asp.net应用服务器是无法区别这是正常点击按钮添加还是f5刷新添加,那么这样就会导致在数据库里会存在n条一模一样的数据。在解决这个问题的过程中,尝试了以下几种方法:
(1)在事件提交后,将其中的参数置空,使得程序在执行过程中,因为没有参数而不会做业务处理。这种处理方法没有效果,因为服务器执行的是上一次请求的事件,事件提交后,改变参数没有任何意义。
(2)在事件提交后,将页面进行重定向到当前页面(Response.Redirect( "/basedata/PictureAdd.aspx" , true);)。因为每个页面都具有自己的生命周期,进行重定向后,即结束了当前页面操作。这种方法可行!
为什么在原Asp开发程序中不会碰到这样的问题呢?我觉得是因为Asp程序主要都是将表单提交给另外一个页面处理,并且,这个页面处理之后,将跳转到另外一个提示页面。那么在Asp程序中,只需要在回退时将页面设置为过期那么就可以有效的避免重复提交的问题。但是在Asp.Net中,基本上所有的操作都是基于事件操作,而事件的本质上就是页面自己提交给自己,并且页面无法识别提交时正常操作还是重复刷新。

以下是非F5刷新重复提交解决方法:
1.
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("if (typeof(Page_ClientValidate) == ’function’)
{ if (Page_ClientValidate() == false)
{ return false; }}");//保证验证函数的执行
sb.Append("if(window.confirm(’提醒:您确定要进行此次操作吗?’)==false) return false;");//自定义客户端脚本
sb.Append("disableOtherSubmit();");// disable所有submit按钮
sb.Append(ClientScript.GetPostBackEventReference(this.btnSubmit,null));//用__doPostBack来提交,保证按钮的服务器端click事件执行
sb.Append(";");
btnSubmit.Attributes.Add("onclick", sb.ToString());
2
页面中捕获回车事件,发现提交表单时,会重复提交,最后在方法后面加一个return false,问题才得以解决。 document.onkeydown=function() {//捕捉回车 if (event.keyCode==13) { checkFormValidate(); return

false; } }  

3、
/// <summary>
    /// 防止重复提交
    /// </summary>
    /// <param name="imaButtons">按键集合</param>
    /// <param name="clientID">页面有JS验证的组件</param>
    public void RepeatSubmitCheckForRC( List<ImageButton> imaButtons)
    {
        foreach (ImageButton button in imaButtons)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("if (typeof(Page_ClientValidate) == &rsquo;function&rsquo;) { if (Page_ClientValidate() == false) { return false; }};");
            if (button.ID != "saveButton")
            {
                sb.Append("if(!contentRequiredValidator()){return false};");//富文本编辑为空验证
            }
            sb.Append("this.disabled  = true;");
            sb.Append(this.Page.ClientScript.GetPostBackEventReference(button, ""));
            sb.Append(";");
            button.Attributes.Add("onclick", sb.ToString());
        }
    }


调用方法的时候

        List<ImageButton> imaButtons = new List<ImageButton>();
        imaButtons.Add(sumbitButton);
        imaButtons.Add(saveButton);
        RepeatSubmitCheckForRC(imaButtons);

4、
ASP.NET项目中经常会遇到这样的情况:页面提交后需要很长的处理时间,用户耐心受到挑战就开始摧残页面上的提交按钮,造成了该页面重复提交多次,带来意想不到的问题。

       在项目实践中,采用了一种比较简单的方式解决这种问题:用户点击提交按钮后,通过JavaScript脚本将提交按钮disable掉,同时显示动画提示用户系统正在处理,并触发服务器端事件。具体是通过在Page_Load事件

中添加如下代码实现的:

        //sb保存的是JavaScript脚本代码,点击提交按钮时执行该脚本
        StringBuilder sb = new StringBuilder();
        //保证验证函数的执行
        sb.Append("if (typeof(Page_ClientValidate) == &rsquo;function&rsquo;) { if (Page_ClientValidate() == false) { return false; }};");
        //点击提交按钮后设置Button的disable属性防止用户再次点击,注意这里的this是JavaScript代码
        sb.Append("this.disabled  = true;");
        //用__doPostBack来提交,保证按钮的服务器端click事件执行
        sb.Append(this.ClientScript.GetPostBackEventReference(this.btnSubmit, ""));
        sb.Append(";");
        //SetUIStyle()是JavaScript函数,点击提交按钮后执行,如可以显示动画效果提示后台处理进度
        //注意SetUIStyle()定义在aspx页面中
        sb.Append("SetUIStyle();");
        //给提交按钮增加OnClick属性
        this.btnSubmit.Attributes.Add("onclick", sb.ToString());

       代码中添加了比较详细的注释,具体就不多解释了。 但实际上这是一种治标不治本的方法,这种方法是不能防止用户按F5刷新的,但用在因为后台的耗时操作叫用户不耐烦引起的重复提交场景上应该是没什么问题的
5、
3.解决刷新页面造成数据重复提交的方法(转载)
public class RefreshServe : System.Web.UI.Page   
{       

 private static ILog log = LogManager.GetLogger(typeof(RefreshServe));       
 private readonly string REFRESH_TICKET_NAME = "__RefreshTicketArray";       
 private readonly string HIDDEN_FIELD_NAME = "__RefreshHiddenField";       
 private readonly string HIDDEN_PAGE_GUID = "__RefreshPageGuid";       
/// <summary>        /// 为True表示页面刷新,False为正常提交      
 /// </summary>
public bool IsPageRefreshed      
 {           
  get {
   if (IsPostBack && !CheckRefreshFlag())
  {  log.Debug("刷新了页面");
     return true;
   }
 else
  { 
  log.Debug("正常提交");
 return false;
  }           
}       
}       
/// <summary>       
/// 呈现前更新标识       
/// </summary>       
/// <param name="e"></param>
protected override void OnPreRender(EventArgs e)       
{           
  log.Debug("执行OnPreRender");
   base.OnPreRender(e);
   UpdateRefreshFlag();       
}       
/// <summary>       
/// 更新标识,正常提交都删除该次提交的时间,并生产当前新的时间       
/// </summary> private void UpdateRefreshFlag()       
{           
 #region Cookie模式
//注册页面唯一标识并返回
string pageGuid = SetCurPageGuid();            HttpCookie cookie = GetRefreshTicket();                      
if (cookie.Values.Count > 0)

 cookie.Values.Remove(pageGuid);
  log.Debug("当前清除的cookie变是:" + pageGuid);
}           
string submitTime = DateTime.Now.ToString("hhmmss.fffff");           
//当前提交时间保存到隐藏域           
ClientScript.RegisterHiddenField(HIDDEN_FIELD_NAME, submitTime);           
log.Debug("即将要新增的时间:submitTime:" + submitTime + "  Guid:" + pageGuid.ToString());           
cookie.Values.Add(pageGuid, submitTime);            log.Debug("UpdateRefreshFlag中当前Cookie中存在的记录数为:" + cookie.Values.Count);           
for (int i = 0; i < cookie.Values.Count; i++)                l
og.Info("cookie[" + cookie.Values.GetKey(i) + "]:" + cookie.Values[i]);           
Response.AppendCookie(cookie);           
#endregion       
}       
/// <summary>       
/// 验证是否刷新       
/// </summary>       
/// <returns></returns>
private bool CheckRefreshFlag()       
{           
HttpCookie cookie = GetRefreshTicket();           
string pageGuid = GetCurPageGuid();           
if (cookie.Values.Count > 0)          
{  
  bool flag;               
  if (cookie.Values[pageGuid] != null)                   
  flag = cookie.Values[pageGuid].IndexOf(GetCurSubmitTime()) > -1;               
else
   flag = true;//防止出现异常,总是可以提交
    if (flag)                   
    log.Debug("提交时间存在,可以提交");               
   else                   
   log.Debug("无效的提交时间");           return flag;           

}           
return true;       
}       
/// <summary>       
/// 得到已保存的提交时间,没有新建,有返回       
/// </summary>       
/// <returns></returns>
private HttpCookie GetRefreshTicket()       
{   
   #region Cookie模式,返回值为Cookie           
    HttpCookie cookie;           
   if (Request.Cookies[REFRESH_TICKET_NAME] == null)            {               
   cookie = new HttpCookie(REFRESH_TICKET_NAME);               
    Response.AppendCookie(cookie);               
     log.Debug("Cookie不存在,初始化");           
}           
else            {               
cookie = Request.Cookies[REFRESH_TICKET_NAME];               
log.Debug("读取已存在的Cookie,当前Cookie中存在的记录数为:" + cookie.Values.Count + "具体有如下几条:");                for (int i = 0; i < cookie.Values.Count; i++)                  
 log.Info("cookie[" + cookie.Values.GetKey(i) + "]:" + cookie.Values[i]);           
}           
return cookie;            #endregion       
}       
/// <summary>       
/// 获取当前提交时间       
/// </summary>       
/// <returns></returns>
private string GetCurSubmitTime()       
{           
string submitTime = Request.Params[HIDDEN_FIELD_NAME] == null ? "" : Request.Params[HIDDEN_FIELD_NAME].ToString();        
   log.Debug("执行GetCurSubmitTime:submitTime为:" + submitTime);           
return submitTime; }       
/// <summary>       
/// 设置页面唯一标识,通过Guid标识来区分每个页面自己的提交时间       
/// </summary>
private string SetCurPageGuid()       
{          
 string guid;            if (!IsPostBack)           
{               
if (Request.Params[HIDDEN_PAGE_GUID] == null)              
 {                   
guid = System.Guid.NewGuid().ToString();                 
  log.Debug("SetCurPageGuid注册了一个新的标识:" + guid);              
 }             
  else                  
guid = GetCurPageGuid();          
 }          
 else           
{              
 guid = GetCurPageGuid();                          
}          
 ClientScript.RegisterHiddenField(HIDDEN_PAGE_GUID, guid);           
return guid;      
 }       
 /// <summary>      
 /// 得到当前页面的唯一标识       
/// </summary>       
/// <returns></returns>
private string GetCurPageGuid()      
 {           
   string pageGuid = Request.Params[HIDDEN_PAGE_GUID] == null ? "none" : Request.Params[HIDDEN_PAGE_GUID].ToString();           
log.Debug("执行GetCurPageGuid()后Page_GUID为:" + pageGuid);          
 return pageGuid;       
}需要刷新判断功能时新页面只需继承该类就可,通过引用属性IsPageRefreshed识别"为真表示刷新,假则是正常提交",将数据库的操作写在if(!IsPageRefreshed){   数据库操作}即可,如果是刷新不会执行,代码中注释部分使用的是Session方式保存票证,因为session比较容易丢失且占内存,所以使用cookie,本文由
长沙专业做网站整理,转载请注明www.sendawangluo.com
 

版权所有:长沙森达网络工作室2011-2016 All Rights Reserved 地址:长沙市岳麓区中电软件园总部大楼 网站备案号:湘ICP备11005944号