快速业务通道

用Response.Redirect,彻底解决刷新重复提交问题

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-04-12

以前也研究过,始终没找到好的办法,看了微软Msdn上的解决方案,使用后发现存在较多漏洞,考虑的情况太少,如页面加载后没有提交,始终刷新,在同一浏览器打开多个各选项卡,每个选项卡打开同一页面或不同页面,以下是我的解决方案,
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++)
                log.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;
        }

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号