Mt textbook says TempData persists until it is read, which means it will get destroy after it has been read, but I do see some code in a view like this:
@if (TempData["message"] != null)
{
<div class="alert alert-success">@TempData["message"]</div>
}
so I'm confused, isn't that TempData["message"] != null
already access TempData, how come it can still be accessed in the <div>
?
another question is that, let's say we have a XXXController and one of action method uses TempData as:
[HttpPost]
public IActionResult Edit(Product product)
{
...
TempData["message"] = $"{product.Name} has been saved";
...
}
when doing unit testing using Xunit and Moq,code is like this:
Mock<ITempDataDictionary> tempData = new Mock<ITempDataDictionary>();
XXXController target = new XXXController(mock.Object)
{
TempData = tempData.Object
}
why do I need to initial the TempData, isn't that when controller instanced is created, we can assign TempData immediately?
Isn't that
TempData["message"] != null
already accessingTempData
, how come it can still be accessed in the<div>
?
Yes, TempData["message"] != null
is accessing the temp data value, so it is being marked as to not persist for the next request.
Temp data is persisted for the next request unless it is read. It is however not removed immediately. So you can read the same temp data multiple times while handling the same request, but it just won’t be around for the next request.
The logic is basically that the temp data provider keeps track of the dictionary and what keys it should persist for the next request. It starts with every key from the dictionary, so everything is being persisted for the next request. When you access a value, then that key is being removed from the list of keys to persist. And when you set a value, then that key is being added to the list of keys to persist.
Why do I need to initialize the
TempData
, isn't that when controller instanced is created, we can assignTempData
immediately?
Controllers by default don’t actually have much stuff in them. The framework is built in a way so that you don’t actually need to inherit from Controller
or ControllerBase
and you still can create a perfectly fine controller. The accessors like HttpContext
, ViewData
, or TempData
, are just empty slots that will eventually be filled when ASP.NET Core executes an action. They are however not automatically set during creation.
That means that in a test, where ASP.NET Core does not execute the action for you, you will have to take care of this yourself and set up these slots yourself. So if you depend on any of these properties, you will have to create them first before you can test them.