How to avoid adding repeat submit the same data if you click the 'Refresh' button of Browser?

After reading this book(Programming Microsoft ASP.NET 2.0 Applications - Advanced Topics), I get some ideas about this issue.

Usually, we may need to avoid doing the repeat operation when the user click the 'Refresh' button of Browser. How to prevent it?

Actually, we can save the operation times for each request page in HashTable in Custom HttpModule.

   DownLoad

//Page

using System;
using System.Web;
using System.Web.UI;

namespace ProAspNet20.Advanced.CS.Components
{
    
public class Page : System.Web.UI.Page
    {
        
#region New Properties

        
public bool IsRefreshed 
        {
            
get
            {
                
object o = HttpContext.Current.Items[RefreshAction.PageRefreshEntry];
                
if (o == null)
                    
return false;
                
return (bool) o;
            }
        }
        
#endregion


        
#region Overrides
        
// **************************************************************
        
// Handle the PreRenderComplete event
        protected override void OnPreRenderComplete(EventArgs e)
        {
            
base.OnPreRenderComplete(e);
            SaveRefreshState();
        }
        
#endregion


        
#region Helpers
        
// **************************************************************
        
// Create the hidden field to store the current request ticket
        private void SaveRefreshState()
        {
            
int ticket = (int)HttpContext.Current.Items[RefreshAction.NextPageTicketEntry];
            ClientScript.RegisterHiddenField(RefreshAction.CurrentRefreshTicketEntry, 
                ticket.ToString());
        }
        
#endregion
    }
}

//Reresh Action

using System;
using System.Web;
using System.Collections;


namespace ProAspNet20.Advanced.CS.Components
{
    
public class RefreshAction
    {
        
#region Constants
        
// ***********************************************************
        
// Constants
        public const string LastRefreshTicketEntry = "__LASTREFRESHTICKET";
        
public const string CurrentRefreshTicketEntry = "__CURRENTREFRESHTICKET";
        
public const string PageRefreshEntry = "IsRefreshed";
        
public const string NextPageTicketEntry = "__NEXTPAGETICKET";
        
#endregion

        
static Hashtable requestHistory = null;

        
// ***********************************************************
        
// Manage to check if the F5 button has been pressed
        public static void Check(HttpContext ctx)
        {
            
// Initialize the ticket slot
            EnsureRefreshTicket(ctx);

            
// Read the last ticket served in the session (from Session)
            int lastTicket = GetLastRefreshTicket(ctx);

            
// Read the ticket of the current request (from a hidden field)
            int thisTicket = GetCurrentRefreshTicket(ctx, lastTicket);

            
// Compare tickets
            if (thisTicket > lastTicket || 
                (thisTicket
==lastTicket && thisTicket==0))
            {
                UpdateLastRefreshTicket(ctx, thisTicket);
                ctx.Items[PageRefreshEntry] 
= false;
            }
            
else
            {
                ctx.Items[PageRefreshEntry] 
= true;
            }
        }
         
        
// ***********************************************************
        
// Initialize the internal data store 
        private static void EnsureRefreshTicket(HttpContext ctx)
        {
            
// Initialize the session slots for the page (Ticket) and the module (LastTicketServed)
            if (requestHistory == null)
                requestHistory 
= new Hashtable();
        }


        
// ***********************************************************
        
// Return the last-served ticket for the URL
        private static int GetLastRefreshTicket(HttpContext ctx)
        {
            
// Extract and return the last ticket
            if (!requestHistory.ContainsKey(ctx.Request.Path))
                
return 0;
            
else
                
return (int) requestHistory[ctx.Request.Path];
        }
        

        
// ***********************************************************
        
// Return the ticket associated with the page
        private static int GetCurrentRefreshTicket(HttpContext ctx, int lastTicket)
        {
            
int ticket;
            
object o = ctx.Request[CurrentRefreshTicketEntry];
            
if (o == null)
                ticket 
= lastTicket;
            
else
                ticket 
= Convert.ToInt32(o);

            ctx.Items[RefreshAction.NextPageTicketEntry] 
= ticket + 1;
            
return ticket;
        }
        

        
// ***********************************************************
        
// Store the last-served ticket for the URL
        private static void UpdateLastRefreshTicket(HttpContext ctx, int ticket)
        {
            
// Item overwrites, Add does not
            requestHistory[ctx.Request.Path] = ticket;
        }
    }
}

//RereshModule

using System;
using System.Web;
using System.Web.SessionState;


namespace ProAspNet20.Advanced.CS.Components
{
    
public class RefreshModule : IHttpModule
    {
        
#region IHttpModule
        
// ***********************************************************
        
// IHttpModule::Init
        public void Init(HttpApplication app)
        {
            
// Register for pipeline events
            app.BeginRequest += new EventHandler(this.OnAcquireRequestState);
        }
        
// ***********************************************************
        
// IHttpModule::Dispose
        public void Dispose() 
        {
        }
        
#endregion


        
#region Helpers
        
// ***********************************************************
        
// Determine if a F5 or back/fwd action is in course
        private void OnAcquireRequestState(object sender, EventArgs e)
        {
            
// Get access to the HTTP context 
            HttpApplication app = (HttpApplication)sender;
            HttpContext ctx 
= app.Context;

            
// Check F5 action
            RefreshAction.Check(ctx);

            
return;
        }
        
#endregion
    }
}

//TestRefresh

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TestRefresh.aspx.cs" Inherits="TestRefresh" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title>Test Refresh</title>
</head>
<body>
        
<form id="Form1" method="post" runat="server">
            
<table border="2">
                
<tr>
                    
<td bgcolor="yellow" rowspan="2">
                        
<h1 id="Msg" runat="server"></h1>
                    
</td>
                
</tr>
            
</table>
            
<hr>
            
<asp:textbox id="FName" runat="server" text="Dino" />
            
<asp:textbox id="LName" runat="server" text="Esposito" /><br>
            
<asp:button id="AddContactButton" runat="server" text="Add Contact" Font-Bold="True" OnClick="AddContactButton_Click"></asp:button><asp:button id="ResetButton" runat="server" text="Clear Contacts" Font-Bold="True" OnClick="ResetButton_Click"></asp:button>
            
<br>
            
<a target="_blank" href="TestRefresh.aspx">Display a copy of me</a>
            
<hr>
            
&nbsp;<asp:GridView ID="grid" runat="server">
            
</asp:GridView>
        
</form>
</body>
</html>

//Code

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.OleDb;

public partial class TestRefresh : ProAspNet20.Advanced.CS.Components.Page
{
    
protected void AddContactButton_Click(object sender, EventArgs e)
    {
        Msg.InnerText 
= "Added";
        
if (!this.IsRefreshed)
            AddRecord(FName.Text, LName.Text);
        
else
            Msg.InnerText 
= "Page refreshed";
    }

    
protected void ResetButton_Click(object sender, EventArgs e)
    {

    }

    
#region Helpers
    
private void AddRecord(string fname, string lname)
    {
        
    }

    
private void BindData()
    {
         
    }
    
#endregion

}

 //web.config

<httpModules>
      
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      
<add name="Refresh" type="ProAspNet20.Advanced.CS.Components.RefreshModule,ProAspCompLib"/>
</httpModules>

 

posted on 2009-10-31 21:28  博览潇湘  阅读(784)  评论(0)    收藏  举报

导航