TempData只能访问一次?

时间:2019-07-23 06:17:23

标签: c# asp.net-core-mvc razorengine

Mt教科书说TempData一直持续到被读取为止,这意味着它在被读取后将被销毁,但是我确实在这样的视图中看到了一些代码:

@if (TempData["message"] != null)
{
   <div class="alert alert-success">@TempData["message"]</div>
}

所以我很困惑,是不是TempData["message"] != null已经访问了TempData,为什么还可以在<div>中访问它?

另一个问题是,假设我们有一个XXXController,并且其中一个操作方法将TempData用作:

[HttpPost]
public IActionResult Edit(Product product)
{
   ...
    TempData["message"] = $"{product.Name} has been saved";
   ...
}

使用Xunit和Moq进行单元测试时,代码如下:

Mock<ITempDataDictionary> tempData = new Mock<ITempDataDictionary>();
XXXController target = new XXXController(mock.Object)
{
   TempData = tempData.Object
}

为什么我需要初始化TempData,不是在创建控制器实例时就可以立即分配TempData吗?

1 个答案:

答案 0 :(得分:2)

  

不是TempData["message"] != null已经在访问TempData,为什么还可以在<div>中访问它?

是的,TempData["message"] != null正在访问临时数据值,因此将其标记为对下一个请求不持久。

对于下一个请求,临时数据将保留下来,除非已读取。但是,不会立即将其删除。因此,您可以在处理同一请求时多次读取相同的临时数据,但是下一个请求就不会再使用该数据了。

从逻辑上讲,临时数据提供程序会跟踪字典及其在下一个请求中应保留的键。它以字典中的每个键开头,因此所有内容都将保留用于下一个请求。当您访问一个值时,该键将从键列表中删除以保留。而且,当您设置一个值时,该键将被添加到要保留的键列表中。

  

为什么我需要初始化TempData,不是在创建控制器实例时就可以立即分配TempData吗?

默认情况下,控制器中实际上没有很多东西。该框架的构建方式使您实际上不需要继承ControllerControllerBase,并且仍然可以创建一个完美的控制器。诸如HttpContextViewDataTempData之类的访问器只是空插槽,这些空插槽最终将在ASP.NET Core执行操作时被填充。但是,它们不会在创建过程中自动设置。

这意味着在测试中,ASP.NET Core不会为您执行操作,您将必须自己做好这项工作,并自行设置这些插槽。因此,如果您依赖这些属性中的任何一个,则必须先创建它们,然后才能对其进行测试。