刷新后TempData不为空
本文关键字:TempData 刷新 | 更新日期: 2023-09-27 18:12:07
我认为TempData应该在一次刷新或页面重定向后变为空。它需要两次刷新我的页面来清除数据,虽然这不是我想要的,我如何使它在1刷新/重定向后变为空?
@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
}
我最近查看了它的源代码,以了解TempData是如何工作的。
所以tempdata的生命周期是相当不寻常的,因为它只有一个请求。为了实现这一点,它维护了2个hashset来管理键和数据字典:
private Dictionary<string, object> _data;
private HashSet<string> _initialKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private HashSet<string> _retainedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
当您使用索引器或TryGetValue方法读取一些数据时,它会从_initalKeys集合中删除该键。
public bool TryGetValue(string key, out object value)
{
_initialKeys.Remove(key);
return _data.TryGetValue(key, out value);
}
保存数据的实际字典此时是完整的。这就是为什么我们可以连续读取相同的数据而没有任何问题。它只从_initialKeys集合中删除键,基本上将其标记为在数据持久化时删除。
如果你想让你的值在TempData持续更长时间,你可以使用Peek和Keep方法。Peek所做的是返回值而不从_initialKeys中删除它:
public object Peek(string key)
{
object value;
_data.TryGetValue(key, out value);
return value;
}
也可以调用Keep方法。类似地,它不直接操作数据,而只是通过将键添加到_retainedKeys集合来标记要持久化的键。
public void Keep(string key)
{
_retainedKeys.Add(key);
}
最后通过调用提供者的Save方法保存数据(默认情况下保存到Session):
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);
}
因此,只有保留在_initialKeys集合中的数据(未读)和特别指示保留的数据(_retainedKeys集合中的键)将被保存。因此就有了寿命!
参考:TempDataDictionary源代码
我们有不同的状态管理技术,如Viewbag,ViewData和TempData。TempData的特殊之处在于,它甚至可以在多个连续请求中保存该值,这取决于该值在视图中被读取的方式。
-
如果它是一个正常的读取,那么在下一个请求时该值将变为空。2.如果是Peek读取,例如使用了TempData的Peek()方法,则值将保留到下一个请求。3.如果它是一个Keep读,这意味着你已经使用了TempData的Keep()方法,那么这个值也将在下一个请求中可用。4.如果您没有读取视图中的值,则该值将保留,直到未读取为止。
MVC中的TempData与示例
如果您想在请求完成后保留TempData对象中的值,您需要在当前操作中调用keep方法。
教程