Reputation: 7656
I thought TempData was supposed to become null after one refresh or page redirect. It takes two refreshes of my page to clear the data though which isn't what I want, how do I make it go null after 1 refresh/redirect?
@using (Html.BeginForm())
{
<div class="form-group">
<button class="btn btn-default" type="submit">test</button>
</div>
}
public void test()
{
List<int> integers = new List<int>();
integers.Add(10);
integers.Add(20);
//First Refresh and myList still has values when I want it to be null
List<int> myList = (List<int>)TempData["test"]; // Take the value from the current data variable
if (myList == null) // Not yet stored in session, create a new list and store it as a session variable
{
myList = new List<int>();
TempData.Add("test", myList);
}
myList.AddRange(integers); // Add a new entry
}
Upvotes: 0
Views: 2260
Reputation: 71
In Asp.Net MVC we have different techniques for state management like Viewbag,ViewData and TempData. TempData is something special in the sense that it can hold the value even for multiple successive requests depending upon how the value is being Read in the view.
If it is a normal read then the value will become null for next request. 2.If it is a Peek read , like if you have used Peek() method of TempData then value will be retain for the next request. 3.If it is a Keep read, meaning you have used Keep() method of TempData then also the Value will be available for next request. 4.If you have not read the value in the view then the value will be retain untill it is not read.
Upvotes: 0
Reputation: 842
If you want to keep value in TempData object after request completion, you need to call Keep method with in the current action.
Upvotes: -1
Reputation: 6957
I recently went through its source code to find out how TempData works.
So the lifespan of tempdata is rather unusual as it is one request only. In order to achieve this it maintains 2 HashSets to manage keys as well as the data dictionary:
private Dictionary<string, object> _data;
private HashSet<string> _initialKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private HashSet<string> _retainedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
When you read some data using an indexer or TryGetValue method it removes that key from _initalKeys collection.
public bool TryGetValue(string key, out object value)
{
_initialKeys.Remove(key);
return _data.TryGetValue(key, out value);
}
The actual dictionary that holds the data is intact at this point. That's why we can read same data consecutively without any issues. It only removes the key from _initialKeys collection, basically marking it to be deleted when the data is persisted.
If you want your values in TempData last longer you can use Peek and Keep methods. What Peek does is return the value without removing it from the _initialKeys:
public object Peek(string key)
{
object value;
_data.TryGetValue(key, out value);
return value;
}
Alternatively, you can call Keep method. Similarly it doesn't manipulate the data directly but just marks the key to be persisted by adding it to the _retainedKeys collection.
public void Keep(string key)
{
_retainedKeys.Add(key);
}
And it finally saves the data (to Session by default) by calling provider's Save method:
public void Save(ControllerContext controllerContext, ITempDataProvider tempDataProvider)
{
_data.RemoveFromDictionary((KeyValuePair<string, object> entry, TempDataDictionary tempData) =>
{
string key = entry.Key;
return !tempData._initialKeys.Contains(key)
&& !tempData._retainedKeys.Contains(key);
}, this);
tempDataProvider.SaveTempData(controllerContext, _data);
}
So only the data that remained in the _initialKeys collection (unread) and the ones that are specifically instructed to retain (the keys in the _retainedKeys collection) will be saved. Hence the lifespan!
Reference: TempDataDictionary source code
Upvotes: 4