Click here to Skip to main content
13,558,882 members
Click here to Skip to main content
Add your own
alternative version


51 bookmarked
Posted 16 Feb 2009
Licenced CPOL

Page Refresh Detection Using HttpModule

, 17 Feb 2009
Rate this:
Please Sign up or sign in to vote.
How to detect and handle a page refresh using only an HttpModule


This article describes the detection and handling of page refreshes using only an HttpModule.


Critical operations done by web pages (e.g. writing stuff to databases, creating users, or deletion of stuff) should be secured from various actions. These actions are, for example, unauthorized access or multiple execution by simply refreshing the page. When I got into the situation (and also the project) that the refreshing issue came up, the project was already way too big (200+ pages, different kinds of users, etc.) to do anything on a per-page basis.

My colleagues already tried to convince our customer to not use F5 or the Refresh button of their browsers. They agreed, but users make mistakes as everyone knows, so from time to time, they do a page refresh. Since our logging is quite extensive, we were able to detect the error that occurred due to the refresh, but it is not satisfying to discuss with the customer over and over again about this issue.

However, I decided to write an HttpModule that covers this topic somehow. So, I read articles about page refreshing detections on MSDN, and this one: Using an HttpModule to detect page refresh, for instance. But they all required additional work on the web pages. In my case, it was totally OK to redirect refreshed pages, so I decided to take the basic idea on refreshing detection and put it in my own module.

About the Code

The code is written for .NET 1.1, but should work in later versions of .NET also. However, I have not tested it on later versions.

Basic Idea

The basic idea on the solution is to write a hidden field in the page containing a unique key right before the page is transmitted to the client.

Using the Code

Compile the code and add the resulting library to the web.config file, as follows:

  <add name="RefreshDetectionModule" type="HttpModules.RefreshDetectionModule"/>

Page-refresh Detection, Step One

To differ an HTTP-POST from another one, I decided to stick with the idea of injecting a (more or less) unique ID in every page that gets sent to the client. To achieve this, I wrote my own class that inherits from the Stream class and hooked it to the Response.Filter.

private void application_PreRequestHandlerExecute(object sender, EventArgs e)
       HttpApplication application = (HttpApplication)sender;
       HttpContext context = application.Context;
       //write the hidden field only if the request is made to the aspx-handler
         //attach the stream that writes the hidden field
         application.Response.Filter =
           new RefreshDetectionResponseFilter(application.Response.Filter,

The stream-class (RefreshDetectionResponseFilter) basically just needs to override the Write-method. I write the whole stream to a StringBuilder and search in the resulting HTML-text for the form tag. The idea is to place the hidden field right behind the form tag. Once the whole stream is read and stored in the StringBuilder, I start searching for the form-tag by using a Regular Expression. Having the form-tag found, I append the hidden field to it.

public override void Write(byte[] buffer, int offset, int count)
     //Read the buffer from the stream
     string sBuffer = UTF8Encoding.UTF8.GetString(buffer, offset, count);
     //when the end of the html-text is read
     if (endOfFile.IsMatch(sBuffer))
       //append the buffer
       //and fire the matching for the start of the form-tag
       //the form tag contains various additional attributes, therefore
       //a non-greedy expression is used to find the whole opening tag.
       MatchCollection aspxPageMatches =
       //When a form-tag could be found
       if(aspxPageMatches.Count > 0)
           StringBuilder newHtml = new StringBuilder();
           int lastIndex = 0;
           //usually only one form tag should be
           //inside a html-text, but who knows ;)
           for(int i = 0; i < aspxPageMatches.Count; i++)
               //Get the text up to the form tag.
                              aspxPageMatches[i].Index -lastIndex));
               //get the opening form-tag
               string key = aspxPageMatches[i].Value;
               //generate the new hidden field
               string enc = string.Format("\r\n<input id=\"{0}\" type" +
                      "=\"hidden\" name=\"{0}\"  value=\"{1}\"/>",
                      HIDDEN_FIELD_ID, guid);
               //write both the the html-text
               lastIndex = aspxPageMatches[i].Index +
           //append the rest of the html-text
           html = newHtml;
       //write the whole text back to the stream
       byte[] data = UTF8Encoding.UTF8.GetBytes(html.ToString());
       responseStream.Write(data, 0, data.Length);
       //when the end of the html-text is not found yet,
       //write the buffer to the stringbuilder only

When the hidden field is appended, I write everything back to the stream.

Page-refresh Detection, Step Two

Now that all the pages contain the hidden field, I just need to look out for the value of the hidden field, once the page is posted back. To do so, I just hook up to the BeginRequest-event of the HttpModule and look in the posted form for the hidden field. If the value of the hidden field has been posted before, I know that this post is just the refreshing of a previously posted page. In that case, I just do a redirect to the logout-page.

If the value has not been posted before, I write the value to a list (I use a queue for easily dequeueing items when the list exceeds its maximum size).

private void application_BeginRequest(object sender, EventArgs e)
    HttpApplication application = (HttpApplication)sender;
    HttpContext context = application.Context;
    string s = "";
    //Refreshing is only prohibited of the request is a post-request.
        //Get the guid from the http-post form
            s = context.Request.Form[RefreshDetectionResponseFilter.HIDDEN_FIELD_ID];
        //if the guid is already in the queue the post is a refresh
        if(q.Contains(s) && s.Length>0)
            //refresh -> Redirect to any other page
        //when the queue-size exceeded its limit (queueSize), guids will be
        //removed from the queue until the queue size is lower than the limit.
        //since the post is not a refresh the guid is written to the queue

Conclusion and Personal Notes

I wrote this module just to provide an easy way of detecting page-refreshes. In my case, it works good. I'm quite sure there is much to improve, so if anyone has ideas for improvements, I'll be happy to hear them. This is my first article, so please excuse me if I have made any mistakes.


  • 16th February, 2009: Initial post
  • 17th February, 2009: Updated article and added source code


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Jens Meyer
Software Developer
Germany Germany
No Biography provided

You may also be interested in...


Comments and Discussions

QuestionPage Refresh Detection Using HttpModule Pin
Member 366988925-Jul-12 23:10
memberMember 366988925-Jul-12 23:10 
Generalnice.. thanks. Pin
mk.developer30-Nov-10 9:11
membermk.developer30-Nov-10 9:11 
Generaldetect page refresh Pin
Gangadhar Mahindrakar18-Feb-09 19:14
memberGangadhar Mahindrakar18-Feb-09 19:14 
GeneralRe: detect page refresh Pin
Jens Meyer18-Feb-09 20:28
memberJens Meyer18-Feb-09 20:28 
GeneralRe: detect page refresh [modified] Pin
siphu18-Feb-09 22:52
membersiphu18-Feb-09 22:52 
GeneralRe: detect page refresh Pin
Jens Meyer19-Feb-09 1:21
memberJens Meyer19-Feb-09 1:21 
GeneralRe: detect page refresh Pin
Phu Nguyen Si21-Feb-09 18:05
memberPhu Nguyen Si21-Feb-09 18:05 
GeneralWhat's the diffrent with SimoneB's solution Pin
guaike18-Feb-09 16:22
memberguaike18-Feb-09 16:22 
GeneralRe: What's the diffrent with SimoneB's solution Pin
Jens Meyer18-Feb-09 20:40
memberJens Meyer18-Feb-09 20:40 
QuestionSource code? Pin
Michael B. Hansen16-Feb-09 23:40
memberMichael B. Hansen16-Feb-09 23:40 
AnswerRe: Source code? Pin
Jens Meyer17-Feb-09 0:11
memberJens Meyer17-Feb-09 0:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01-2016 | 2.8.180515.1 | Last Updated 17 Feb 2009
Article Copyright 2009 by Jens Meyer
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid