Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Handling ASP.NET Browser Refresh

2.21/5 (12 votes)
27 Jun 20073 min read 3   202  
This article explains a relatively easy and simple approach to distinguishing between a post-back request in ASP.NET and the one generated from the user's browser

Screenshot - images.jpg

Introduction

For years, most ASP.NET developers have been coming across the scenario where hitting the browser's refresh button or pressing the F5 key performs exactly the same steps last performed by their .NET code. To be short and simple, let's create a scenario where I have an ASP.NET application that has a form called Add Customer. This form has a button on it and when the user clicks that button, a customer is added to the file. If the user again hits the Add Customer button, another customer is added to the file. However, if the user presses a refresh button or hits F5 key at this point, exactly the same scenario will be repeated and one more customer is added, as well. Hence in ASP.NET whenever you hit F5, .NET repeats its last action. This happens even when the F5 event is not a genuine post-back event. Needless to say, developers want to get rid of this.

Background

The same problem was faced by my colleague a few days back. We tried a lot searching on the Internet, where we found a few solutions, but those were either just the pseudo-code -- i.e. not properly working -- or something like a hit-and-trial. A few of them jumped straight across the head. Unfortunately, there was not a single solution that could be easily implemented in ASP.NET and justify itself.

After two days of searching on the Internet, I came up with just a little clue, although I don't remember the reference. It suggested that we could distinguish between a genuine post-back request and the one generated by browser's refresh. All server-side events that get fired on the post-back get fired on refresh also, but fortunately there exists one event, onsubmit, that only gets fired when there is a genuine post-back request. It is the client-side event of the form placed on your web page.

Using the code

The logic of the following code is to have a hidden control on your web form and every time there is a genuine post-back request, the client script just appends one character to the existing value of that hidden control. At the server side, I take a shared variable that will retain its value through the application's life, i.e. it won't be written off on every page load.

The first time the page_load event is executed, I assign that shared variable the value of 1. As I've stated, the main task is to distinguish between the genuine post-back request and the refresh one on the Add Customer button. The simple logic is that if it is the first time the event has been executed, then my shared variable will be 1. If it is not the first time, then the character length of the hidden control will be one more than its previous length. I can easily obtain the new length of the control from len(control.value).

Then every time a customer is added, I assign the current control length to that shared variable. Hence, the next time a customer is added, your length should be one more than that of the last time. At every genuine post-back request, a value is appended to the current value of the hidden control in the client-side script, called upon at the onsubmit event of the form.

JavaScript

JavaScript
// The JavaScript Function which gets fired on form submit (onsubmit) when 
// there is a post back request, and appends a flag value to 
// the hidden control 

function AddFlag() 
{ 
    //on every genuine postback request, we append a value to 
    // the existing hidden field value 
    document.getElementById("Flag").value= 
        document.getElementById("Flag").value + 'P'; 
}

Visual Basic

VB
'The Server Side VB.Net Class, containing the shared level variable

Partial Class _Default Inherits System.Web.UI.Page
    Shared done As String 'The shared variable will retain its 
                          'value through the application's life... 

    'Page load event to set value to the variable for the first time

    Protected Sub Page_Load(ByVal sender As Object, 
        ByVal e As System.EventArgs) Handles Me.Load 
        If Not Page.IsPostBack Then 'for the first time 
            done = 1 
        End If
    End Sub

    'The main conditional check in this function 
    'checks for two things, if the request for 
    'this event is for the first time then let it go, 
    'which is pretty obvious, moreover
    'if it's not the first time then for a genuine 
    'postback the current length of characters in 
    'hidden control should be greater then its previous, 
    'as on every genuine post back
    'request it is appending a value to it, if not then 
    'it means this request is generated by the 
    'browser's refresh and hence it would execute the ELSE condition.

    Protected Sub AddCustomer_Click(ByVal sender As Object, 
        ByVal e As System.EventArgs) Handles AddCustomer.Click
        'this condition will check either its the first 
        'time or genuine post back request 

        If Len(Flag.Value) > Len(done) Or done = "1" Then 
            'Write Your Add Customer Code here > Response.Write("true") 
            done = Flag.Value 'substituting variable value 
                              'with the current value of hidden control 
        Else 
            Response.Write("false")
        End If 
    End Sub 
End Class

Points of interest

This solution is appealing in that it is NOT asking you to play with complex things like HTTP headers, HTTP modules, setting sessions from the client, keeping unwanted checks on the code and database level, etc. It can also be applied to any scenario and in any version of ASP.NET where users are facing similar problems. Its solution is very simple and can be understood and applied even by a developer who has just started working with the technology.

History

  • 27 June, 2007 -- Original version posted

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here