4

...in comparison to requests of normal link click behaviour. I thought I might be able to use this to throw away some cached stuff on the serverside. For a more technical orientated target audience this could be a relative natural way of clearing a cache for i.e. graphs and charts.

To be clear - I am using ASP.NET MVC

Dirk Boer
  • 8,522
  • 13
  • 63
  • 111
  • 2
    Use normal cache expiration rules/policies. You can check the cache/etag headers sent from the client and react accordingly - but it might be easiest to say *if* this resource is fetched, then regenerate it and otherwise rely on the client correctly honoring the cache headers sent. – user2864740 Oct 16 '13 at 20:13
  • related: http://stackoverflow.com/questions/8861137/any-way-to-identify-f5-refresh-in-php – Marijn Dec 13 '13 at 09:18
  • Do you care about difference between a refresh and having the same page requested again? – Dave Alperovich Dec 14 '13 at 03:44
  • Maybe this helps: http://superuser.com/questions/17464/difference-between-ctrlrefresh-and-ctrlshiftrefresh – Lajos Veres Dec 15 '13 at 09:30

4 Answers4

4

I've just checked the three browsers you're likely to care about, and all three add extra cache headers in the request when you refresh the page. Conceivable you could check for those headers to throw out some server-side cache. It also seems a logical and natural way to do it.

  • IE: adds "Pragma: no-cache"
  • Chrome: adds "Cache-Control: max-age=0" and "If-Modified-Since: Tue, 17 Dec 2013 10:16:22 GMT" (disclaimer: time may vary)
  • Firefox: adds "Cache-Control: max-age=0"

I just checked this by refreshing this page in all three browsers, and checking Fiddler. It is possible there is more sophisticated logic going on that I haven't caught on to.

Menno van den Heuvel
  • 1,851
  • 13
  • 24
2

Since it's in MVC, I would use the TempData to achieve this. On the first load of your method, you can set a value in the TempData so on the next load(the refresh) you would have a value set in this.

Let say you have a Add method, I think that should do the trick :

public virtual ActionResult Add(Model model)
        {
            if(TempData.ContainsKey("yourKey"))
            {
                //it means that you reload this method or you click on the link
                //be sure to use unique key by request since TempData is use for the next request 
            }

            TempData.Add("yourKey", true);

            return View(model);
        }
VinnyG
  • 6,883
  • 7
  • 58
  • 76
1

Add this script to your head section:

<script>
        $(window).keydown(function (e) {
            if (e.which == 116) {
                e.preventDefault();
                var l = window.location;
                var lp = (l + "?").split('?');
                window.location = lp[0] + "?f5=1&" + lp[1];
                return false;
            }
        });
    </script>

In server side just check if Request["f5"]=="1"

If you prefer not to modify the URL, you may add a temporary cookie. something like this:

<script>
        $(window).keydown(function (e) {
            if (e.which == 116) {
                AddCookie("F5","1")
            }
        });
</script>

On page load check if the cookie exists and delete it for next request.

Hossein
  • 1,640
  • 2
  • 26
  • 41
0

You could compare the current session ID to the last page that was loaded and then compare the IsPostBack command.

If IsPostBack is true you know the user has clicked something on that page to post the page back. If the last page that was retrieved for the current session ID was not the same as the page you are currently loading then they arrived at this page from another page. If the last page that was retrieved is the same for the current session ID as the current page you are processing then this was likely a refresh (F5).

The only problem would be that you would detect F5 the same as someone putting their cursor in the address bar and hitting the Enter key once the page had finished loading, but I doubt this would be a problem for you.

EDIT: There seems to be some confusion on the comments about how this system would work so let me explain further. As was pointed out to me IsPostBack is not available in MVC so you have to test for post backs as shown here:

ASP.NET MVC - Is IsPostBack still here?

Let us consider the three ways in which you can end up at a page, any page. For our examples let us assume we want to detect refreshes on page X.

You can get to Page X these ways: 1. User presses a button on page A which takes you to page X. 2. User presses a button on Page B which posts you back to page B (post back). 3. User presses F5 or reloads the page some other way. - this is the one we want to detect..

There is scenario 4 which is 'user comes to page X from another site' but this would start a new session so let us not consider this.

Everytime a user loads a page you store that page somewhere along with the SessionID. The SessionID is constant for any one user for the duration of the session time out. There are some caveats to this such as accessing from different browsers on a single machine but I do not want to confuse matters.

Scenario 1: User loads page A, we look in our memory and there are no records at present. We store 'Page A' and the sessionID in memory. User clicks button on Page A. User is redirected, posts or transferred to Page B. Page B loads, we check the 'IsPostBack' flag, it may or may not be true at this point. If it is we know it is not a refresh, if it is false we need to continue to test as follows. we look in our memory and there is a record for 'Page A' for the current Session ID (remember the session ID does not change between requests for any given user). because the previous page was 'Page A' and we are on Page B we know this is NOT a refresh. We store 'Page B; and the sessionID in memory (in practice we either erase or update the previous record pointing to Page A).

Scenario 2: User loads page B, we store 'Page B' and the sessionID in memory. User clicks a button on page B. Page B loads, we check 'IsPostBack' flag. It is true so we know this is not a refresh.

Scenario 3: User loads Page B, we store 'Page B' and the sessionID in memory. User refreshes the page or reloads it by putting their cursor in the address bar and hitting enter. Page B loads, we check the 'IsPostBack' flag, it is false so we need to continue to test as follows. we look in our memory and there is a record for 'Page B' for the current Session ID. Because the previous page was 'Page B' and we are on Page B we know this IS a refresh.

By using this approach you can detect refreshes. If you are using MVC you can test Request.HttpMethod=="POST"

The only problem you get is if the user does a POST, you do a redirection, then the user goes back one page and refreshes from there are is will resubmit the form, sending the POST again. This will be detected as a fresh submission when it is actually a refresh. This can be eliminated using a Nonce approach or something similar.

Community
  • 1
  • 1
Craig Moore
  • 1,093
  • 1
  • 6
  • 15
  • 1
    SessionId will not change except until user session is ended or you manage your session to change on every request. – Hossein Dec 11 '13 at 21:19
  • Yes, that's the idea. You know the session ID will not change so you use that to know if two successive requests are from the same user. – Craig Moore Dec 12 '13 at 07:47
  • 1
    Craig, I think you misunderstand. Session ID will NOT help you distinguish between an initial request and refresh. The session ID will be the same. The answer and response are nonsensical. Also, `IsPostBack` doesn't exist in **MVC**. Only your last point was relevant; there is a difficulty in distinguishing between a refresh and another url request. That was the point. – Dave Alperovich Dec 13 '13 at 02:19
  • I did not know that isPostBack does not exist in MVC, it does work within WebForms though as I currently use this approach. – Craig Moore Dec 13 '13 at 18:20
  • I have expanded my response to explain further and to try to clear up the apparent confusion around using this method. – Craig Moore Dec 13 '13 at 18:37
  • Craig, you still haven't explained how sessionID could possibly change without session expiring. Or, what that has to do with a refresh. – Dave Alperovich Dec 14 '13 at 03:39
  • What makes you think the session ID is changing? I haven't said that at any point. You use the Session ID to identify the user so that you know who made any two successive requests. The session ID does not change, that's the whole point. If session ID 123456 opened page B on their last request, and session ID 123456 is opening page B on their current request then that single user has opened the same page twice in a row. – Craig Moore Dec 14 '13 at 11:48