【ASP.NET基础】.net 防止页面刷新重复提交(转载自----->Warren专栏)

在客户端保存一个标志,在服务端也保存一个标志,在提交时对比两个标志的值,来判断是否是重复提交。
先看下面代码,首先是一个RefreshAction静态类,这个类主要是用来初始化服务端Session保存上一次票证的值并且对比客户端和服务端票证的值,当检测到刷新不是重复刷新时,将要把客户端的票证值更新到服务端

[c-sharp] view plaincopy 
public static class RefreshAction  
{  
    // 常量  
    //服务端票证key  
    public const string LastRefreshTicketEntry = "__LASTREFRESHTICKET";  
    //客户端票证key  
    public const string CurrentRefreshTicketEntry = "__CURRENTREFRESHTICKET";  
    //用来保存是否是重复刷新的属性的key  
    public const string PageRefreshEntry = "IsPageRefresh";  
    private static Hashtable requestHistory = null; //存储请求历史  
    // 检测F5按钮是否被按下  
    public static void Check(HttpContext ctx)  
    {   
        //初始化服务端票证  
            EnsureRefreshTicket(ctx);  
            //从Session里读取上一次提供的票证  
            int lastTicket = GetLastRefreshTicket(ctx);  
            //从请求里的隐藏域里读取当前页面的票证  
            int thisTicket = GetCurrentRefreshTicket(ctx);  
            // 对比两个票证  
            if (thisTicket > lastTicket ||  
                (thisTicket == lastTicket && thisTicket == 0))  
            {  
                //如果当前的票证值大于上一次的票证值 或者  
                //当前票证值等于上一次票证值,并且当前票证值为0(这是第一次刷新)  
                //那么更新Session里上一次的票证值为当前票证值  
                UpdateLastRefreshTicket(ctx, thisTicket);  
                //设置当前页是否重复刷新属性为false  
                ctx.Items[PageRefreshEntry] = false;  
            }  
            else  
            {  
                //设置当前页是否重复刷新属性为true;  
                ctx.Items[PageRefreshEntry] = true;  
            }  
    }  
    //确认上一次的票证不为空值  
    static void EnsureRefreshTicket(HttpContext ctx)  
    {  
          
        if (requestHistory == null)    
            requestHistory = new Hashtable();    
    }  
    //得到上一次请求的票证值  
    static int GetLastRefreshTicket(HttpContext ctx)  
    {  
        if (!requestHistory.ContainsKey(ctx.Request.Path))    
            return 0;  
        else     
            return (int) requestHistory[ctx.Request.Path];    
    }  
    //从当前请求里的到隐藏域里保存的当前票证值  
    static int GetCurrentRefreshTicket(HttpContext ctx)  
    {  
        return Convert.ToInt32(ctx.Request[CurrentRefreshTicketEntry]);  
    }  
    // 将当前的票证值保存到Session里的上一次刷新的票证值  
    private static void UpdateLastRefreshTicket(HttpContext ctx, int ticket)  
    {  
        requestHistory[ctx.Request.Path] = ticket;  
    }  
}//end class  

下面是一个HttpModule类,在请求开始时就来检测双方的票证值

[c-sharp] view plaincopy 
public class RefreshModule : IHttpModule  
{  
    public RefreshModule()  
    {  
        //  
        // TODO: Add constructor logic here  
        //  
    }  
    #region IHttpModule Members  
    public void Dispose()  
    {  
        throw new NotImplementedException();  
    }  
    public void Init(HttpApplication app)  
    {  
        //注册请求关联状态时的事件处理器,就是说当一个请求到达服务器,  
        //那么首先触发这个事件,由OnAcquireRqeustState事件处理  
        app.AcquireRequestState += new EventHandler(this.OnAcquireRequestState);  
    }  
    #endregion  
    private void OnAcquireRequestState(object sender, EventArgs e)  
    {  
        HttpApplication app = sender as HttpApplication;  
        HttpContext ctx = app.Context;  
        RefreshAction.Check(ctx); //RefreshAction类来检查当前请求的上下文 Rey  
        return;  
    }  
}//end class  

 

[c-sharp] view plaincopy
 
 
  1. public class RefreshModule : IHttpModule  
  2. {  
  3.     public RefreshModule()  
  4.     {  
  5.         //  
  6.         // TODO: Add constructor logic here  
  7.         //  
  8.     }  
  9.     #region IHttpModule Members  
  10.     public void Dispose()  
  11.     {  
  12.         throw new NotImplementedException();  
  13.     }  
  14.     public void Init(HttpApplication app)  
  15.     {  
  16.         //注册请求关联状态时的事件处理器,就是说当一个请求到达服务器,  
  17.         //那么首先触发这个事件,由OnAcquireRqeustState事件处理  
  18.         app.AcquireRequestState += new EventHandler(this.OnAcquireRequestState);  
  19.     }  
  20.     #endregion  
  21.     private void OnAcquireRequestState(object sender, EventArgs e)  
  22.     {  
  23.         HttpApplication app = sender as HttpApplication;  
  24.         HttpContext ctx = app.Context;  
  25.         RefreshAction.Check(ctx); //RefreshAction类来检查当前请求的上下文 Rey  
  26.         return;  
  27.     }  
  28. }//end class  
posted @ 2017-07-08 14:17  OldELeven  阅读(68)  评论(0编辑  收藏  举报