ASP.NET MVC does browser refresh make TempData useless?
Asked Answered
M

6

10

If I redirect to a new page passing TempData to initialise the page it works fine, however if the user presses the refresh button in their browser the TempData is no-longer available. Given this, is there any situation where TempData could be used reliably?
Or any way to remove or mitigate the problem of users refreshing?

Meatiness answered 15/4, 2010 at 1:2 Comment(0)
F
13

In MVC 1, yes, temp data is lost after the next request after you store a key.

With MVC 2 however, the temp data is lost after the first attempt to access it.

You can always use Session, which TempData uses anyway, to solve the temp data loss issue your having.

From the MVC 2 Beta Release Notes:

TempDataDictionary Improvements

The behavior of the TempDataDictionary class has been changed slightly to address scenarios where temp data was either removed prematurely or persisted longer than necessary. For example, in cases where temp data was read in the same request in which it was set, the temp data was persisting for the next request even though the intent was to remove it. In other cases, temp data was not persisted across multiple consecutive redirects.

To address these scenarios, the TempDataDictionary class was changed so that all the keys survive indefinitely until the key is read from the TempDataDictionary object. The Keep method was added to TempDataDictionary to let you indicate that the value should not be removed after reading. The RedirectToActionResult is an example where the Keep method is called in order to retain all the keys for the next request.

You can also look directly in the MVC 2 source to see these changes:

MVC 1:

  public object this[string key] {
        get {
            object value;
            if (TryGetValue(key, out value)) {
                return value;
            }
            return null;
        }
        set {
            _data[key] = value;
            _modifiedKeys.Add(key);
        }
    }

MVC 2:

   public object this[string key] {
        get {
            object value;
            if (TryGetValue(key, out value)) {
                _initialKeys.Remove(key);
                return value;
            }
            return null;
        }
        set {
            _data[key] = value;
            _initialKeys.Add(key);
        }
    }
Fungoid answered 15/4, 2010 at 1:8 Comment(4)
It's based on accessing the value now? I missed that changelog.Retsina
Yeah, can you provide a reference for the TempData being lost on first access attempt?Lawana
@Nathan Taylor @Baddie, hope my edit and citations remove your concerns.Fungoid
Excellent. Did not know about that change.Retsina
P
25

You should write

TempData.Keep("nameofthedata");

in your controller, then it will keep that data in refresh situations too.

Protractile answered 30/10, 2011 at 21:47 Comment(0)
F
13

In MVC 1, yes, temp data is lost after the next request after you store a key.

With MVC 2 however, the temp data is lost after the first attempt to access it.

You can always use Session, which TempData uses anyway, to solve the temp data loss issue your having.

From the MVC 2 Beta Release Notes:

TempDataDictionary Improvements

The behavior of the TempDataDictionary class has been changed slightly to address scenarios where temp data was either removed prematurely or persisted longer than necessary. For example, in cases where temp data was read in the same request in which it was set, the temp data was persisting for the next request even though the intent was to remove it. In other cases, temp data was not persisted across multiple consecutive redirects.

To address these scenarios, the TempDataDictionary class was changed so that all the keys survive indefinitely until the key is read from the TempDataDictionary object. The Keep method was added to TempDataDictionary to let you indicate that the value should not be removed after reading. The RedirectToActionResult is an example where the Keep method is called in order to retain all the keys for the next request.

You can also look directly in the MVC 2 source to see these changes:

MVC 1:

  public object this[string key] {
        get {
            object value;
            if (TryGetValue(key, out value)) {
                return value;
            }
            return null;
        }
        set {
            _data[key] = value;
            _modifiedKeys.Add(key);
        }
    }

MVC 2:

   public object this[string key] {
        get {
            object value;
            if (TryGetValue(key, out value)) {
                _initialKeys.Remove(key);
                return value;
            }
            return null;
        }
        set {
            _data[key] = value;
            _initialKeys.Add(key);
        }
    }
Fungoid answered 15/4, 2010 at 1:8 Comment(4)
It's based on accessing the value now? I missed that changelog.Retsina
Yeah, can you provide a reference for the TempData being lost on first access attempt?Lawana
@Nathan Taylor @Baddie, hope my edit and citations remove your concerns.Fungoid
Excellent. Did not know about that change.Retsina
V
2

A workaround for the the given situation in MVC1 would be to re-assign the TempData in the second controller as well. Of course it persists the data in the system for a bit more time. but it fixes the refresh issue.

Vertigo answered 21/4, 2010 at 4:36 Comment(1)
it should work in MVC2 as well. But not sure of the implications as it may persist indefinitely if not read again.Vertigo
U
1

Tempdata is used across redirects so if you are refreshing the page that means you are making a separate request to the server so that is why your data gets lost. To persist this data call Tempdata.Keep("KeyofTempdata") method in the action to which you are redirecting. If you want to remove data use Tempdata.Remove("KeyofTempdata").

Unpolite answered 14/2, 2013 at 9:15 Comment(0)
L
0

The only features that can solve your issue is Cache and Session.

ViewData essentially 'dies' out when the view is generated.

If you can provide more details on what you're trying to accomplish, maybe another solution can be given, however, it seems the best option for you is to use Session or Cache.

Lawana answered 15/4, 2010 at 4:27 Comment(1)
In the end I took a completely different approach and passed the data on the query string (it was only a couple of variables but still not the most elegant solution)Meatiness
R
-1

TempData exists specifically to store the data for just one page load/action/redirect. If you need the data to persist after a refresh you should place it in the ViewData collection so long as the action that is serving the refresh request is the same one as was initially requested (i.e. the ViewData value was not added prior to a Redirect).

Retsina answered 15/4, 2010 at 1:9 Comment(2)
Your statement about data persistence using ViewData is incorrect. ViewData's scope ends when the view is generated. Refreshing simply reruns the action and ViewData is regenerated, nothing persists.Lawana
Perhaps I obscured my meaning with how I explained it. I was implying that the value would be re-added to ViewData by way of a refresh.Retsina

© 2022 - 2024 — McMap. All rights reserved.