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吗?
答案 0 :(得分:2)
不是
TempData["message"] != null
已经在访问TempData
,为什么还可以在<div>
中访问它?
是的,TempData["message"] != null
正在访问临时数据值,因此将其标记为对下一个请求不持久。
对于下一个请求,临时数据将保留下来,除非已读取。但是,不会立即将其删除。因此,您可以在处理同一请求时多次读取相同的临时数据,但是下一个请求就不会再使用该数据了。
从逻辑上讲,临时数据提供程序会跟踪字典及其在下一个请求中应保留的键。它以字典中的每个键开头,因此所有内容都将保留用于下一个请求。当您访问一个值时,该键将从键列表中删除以保留。而且,当您设置一个值时,该键将被添加到要保留的键列表中。
为什么我需要初始化
TempData
,不是在创建控制器实例时就可以立即分配TempData
吗?
默认情况下,控制器中实际上没有很多东西。该框架的构建方式使您实际上不需要继承Controller
或ControllerBase
,并且仍然可以创建一个完美的控制器。诸如HttpContext
,ViewData
或TempData
之类的访问器只是空插槽,这些空插槽最终将在ASP.NET Core执行操作时被填充。但是,它们不会在创建过程中自动设置。
这意味着在测试中,ASP.NET Core不会为您执行操作,您将必须自己做好这项工作,并自行设置这些插槽。因此,如果您依赖这些属性中的任何一个,则必须先创建它们,然后才能对其进行测试。