【问题标题】:TempData can only be accessed once?TempData 只能访问一次?
【发布时间】:2019-07-23 06:17:23
【问题描述】:

Mt 教科书说 TempData 在被读取之前一直存在,这意味着它在被读取后会被销毁,但我确实在这样的视图中看到了一些代码:

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

所以我一头雾水,那TempData["message"] != null不是已经访问了TempData,怎么还能在&lt;div&gt;中访问?

另一个问题是,假设我们有一个 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了?

【问题讨论】:

  • TempData 在多个请求中持续存在,直到被读取。 那么它将在 next 请求中不再可用。
  • 这确实是两个独立的问题
  • @HansKesting 哦,你的意思是每个请求都可以使用,而不是一个请求中的每个访问?
  • @HansKesting 那么你能否回答我的第二个问题,为什么如果我不初始化它,那么单元测试会失败(空对象引用)?
  • 是的,完全正确。它在读取后停止持久化

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


【解决方案1】:

TempData["message"] != null不是已经在访问TempData了吗,怎么在&lt;div&gt;里还能访问到?

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

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

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

为什么要初始化TempData,是不是在创建controller instanced的时候就可以马上赋值TempData

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

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

【讨论】:

  • 所以如果我设置TempData["message"] = "xxx",我知道它可以在下一个请求中读取,但是我在下一个请求中也没有读取它怎么办?下一个请求后还能坚持到下一个请求吗?
  • @slowjams 临时数据会一直保留在那里,直到您最终读取或明确删除它。
猜你喜欢
  • 1970-01-01
  • 2020-05-15
  • 2018-08-30
  • 2017-03-20
  • 2020-07-01
  • 2022-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多