TempData 只能访问一次?

TempData can only be accessed once?

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,不是说controller instanced创建的时候就可以直接赋值给TempData吗?

Isn't that TempData["message"] != null already accessing TempData, how come it can still be accessed in the <div>?

是的,TempData["message"] != null 正在访问临时数据值,因此它被标记为不会为下一个请求保留。

除非读取临时数据,否则会为下一个请求保留临时数据。然而,它不会立即被删除。因此,您可以在处理同一个请求时多次读取同一个临时数据,但它不会在下一个请求中出现。

逻辑基本上是临时数据提供者跟踪字典以及它应该为下一个请求保留哪些键。它从字典中的每个键开始,因此所有内容都将保留以供下一个请求使用。当您访问一个值时,该键将从键列表中删除以保留。当您设置一个值时,该键将被添加到要保留的键列表中。

Why do I need to initialize the TempData, isn't that when controller instanced is created, we can assign TempData immediately?

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

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