Question

I understand that are similar question on StackOverflow about this problem, but none of it solved my issue, so i'm creating a new one.

As the title says, i'd like to detect when an user refreshs a page. I have a page where i save some log information about what the user done on it (things like adding, removing or edting items). This log can only be saved when an user leaves the page, not by refreshing it.

I tried the example below to detect if it's a refresh or a new request:

public ActionResult Index()
{
   var Model = new Database().GetLogInfo();
   var state = TempData["refresh"];

   if(state == null)
   {
    //This is a mock structure
    Model.SaveLog(params);
   }


TempData["refresh"] = true; //it can be anything here

return View();
}

Considering it's a TempData it should expire on my next action. However, it's surviving the entire application for some reason. According to this blog it should expire on my subsequent request (unless i'm not understandig something). Even if i log out from my app and log in again, my TempData is still alive.

I've been thinking about use the javascript function onbeforeunload to make an AJAX call to some action, but once again i'd have to rely on TempData or to persist this refresh info somehow. Any tips?

Was it helpful?

Solution

You can use a ActionFilter that looks something like this:

public class RefreshDetectFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var cookie = filterContext.HttpContext.Request.Cookies["RefreshFilter"];
        filterContext.RouteData.Values["IsRefreshed"] = cookie != null &&
                                                        cookie.Value == filterContext.HttpContext.Request.Url.ToString();
    }
    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.SetCookie(new HttpCookie("RefreshFilter", filterContext.HttpContext.Request.Url.ToString()));
    }
}

Register it in global.asax. Then you can just do this in your controller:

if (RouteData.Values["IsRefreshed"] == true)
{
    // page has been refreshed.
}

You might want to improve the detection to also check the HTTP Method used (as a POST and GET url can look the same). Do note that it uses a cookie for the detection.

OTHER TIPS

If you are using MVC 2 or 3 then the TempData does not expire on the subsequent request, but on the next read.

http://robertcorvus.com/warning-mvc-nets-tempdata-now-persists-across-screens/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top