My textbook says that "TempData gets destroyed immediately after it’s used in subsequent HTTP request", so I write a simple test to verify
below is my code:
// SimpleForm.cshtml is just a simple view that uses a form to send post request to ReceiveForm action method
//Result.cshtml is just a simple view that products an output
public class HomeController : Controller
{
public ViewResult Index() => View("SimpleForm");
[HttpPost]
public RedirectToActionResult ReceiveForm(string name, string city)
{
TempData["name"] = name;
TempData["city"] = city;
return RedirectToAction(nameof(Transfer));
}
public RedirectToActionResult Transfer()
{
string name = TempData["name"] as string;
string city = TempData["city"] as string;
return RedirectToAction(nameof(Data));
}
public ViewResult Data()
{
string name = TempData["name"] as string;
string city = TempData["city"] as string;
return View("Result", $"{name} lives in {city}");
}
}
so when the application runs, it goes to Index() action method first, I fill up the form with name and city and press submit button, then it goes to ReceiveForm() action method, which setup TempData and redirect to Transfer() action method.
In the Transfer() action method, I read TempData, so TempData should get destroyed and unavailable to read in the next http request according to the textbook.
But in the Data(), I find that I can still read TempData, see the screenshot below:

and I checked the chrome dev tool, there was one post request and two get requests, which is all good and correct. so when does TempData actually get destroyed ?
additional code:
SimpleForm.cshtml:
@{ Layout = null; }
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Controllers and Actions</title>
<link rel="stylesheet" asp-href-include="lib/bootstrap/dist/css/*.min.css" />
</head>
<body class="m-1 p-1">
<form method="post" asp-action="ReceiveForm">
<div class="form-group">
<label for="name">Name:</label>
<input class="form-control" name="name" />
</div>
<div class="form-group">
<label for="name">City:</label>
<input class="form-control" name="city" />
</div>
<button class="btn btn-primary center-block" type="submit">Submit</button>
</form>
</body>
</html>
Result.cshtml:
@model string
@{ Layout = null; }
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Controllers and Actions</title>
<link rel="stylesheet" asp-href-include="lib/bootstrap/dist/css/*.min.css" />
</head>
<body class="m-1 p-1">
Model Data: @Model
</body>
</html>
For your scenario, this is caused by RedirectToActionResult. For RedirectToActionResult, which is IKeepTempDataResult.
public class RedirectToActionResult : ActionResult, IKeepTempDataResult
SaveTempDataFilter is filter that saves temp data. It will call SaveTempData.
private static void SaveTempData(
IActionResult result,
ITempDataDictionaryFactory factory,
IList<IFilterMetadata> filters,
HttpContext httpContext)
{
var tempData = factory.GetTempData(httpContext);
for (var i = 0; i < filters.Count; i++)
{
if (filters[i] is ISaveTempDataCallback callback)
{
callback.OnTempDataSaving(tempData);
}
}
if (result is IKeepTempDataResult)
{
tempData.Keep();
}
tempData.Save();
}
For SaveTempData, it will check whether IActionResult result is IKeepTempDataResult. If it is, it will keep the tempData.
If you want to avoid keep tempData between request, you could change RedirectToAction to LocalRedirect like
public IActionResult Transfer()
{
string name = TempData["name"] as string;
string city = TempData["city"] as string;
return LocalRedirect("~/Home/Data");
//return RedirectToAction(nameof(Data));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With