The Post-Redirect-Get (PRG) pattern prevents duplicate form submissions when the user refreshes the page. Here's the sequence diagram:
Sequence diagram without TempData
As you can see, the server queries the database twice to display the page to the user. This is inefficient. The time between the two requests is very short, so you can store the object in memory and reuse it for the second request.
The ASP.NET MVC framework provides a mechanism to store data between two requests: TempData. When you use TempData, the value is stored in an encrypted cookie sent to the client. On the next request, the TempData dictionary is restored from that cookie. This means you don't need to reload the data from the database to handle the second request. This is particularly useful in a PRG pattern, since the data is already loaded during the POST request. TempData carries it through to the GET request, avoiding an extra database query.
Sequence diagram with TempData
Let's see how to use TempData!
First you must add the service in the Startup.cs file:
C#
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// Add the temp data provider
services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();
}
Let's create a very simple form:
Razor
@model User
<form asp-controller="Home" asp-action="Edit" method="post">
<input asp-for="Id" />
<input asp-for="DisplayName" />
<button type="submit">Submit</button>
</form>
Here's the controller:
C#
[HttpGet]
public IActionResult Edit(int id)
{
User user = null;
var value = TempData["User"];
if(value is string json)
{
user = JsonConvert.DeserializeObject<User>(json);
}
if (user == null || user.Id != id)
{
user = _userRepository.Load(id);
}
return View(user);
}
[HttpPost]
public IActionResult Edit(User user)
{
_userRepository.Save(user);
TempData["User"] = JsonConvert.SerializeObject(user);
return RedirectToAction("Edit", new { id = user.Id });
}
You can only store string values in the TempData dictionary. A quick workaround is to serialize your data as JSON or in another format. You can also store only the ID and keep the data elsewhere, such as in a static dictionary or a NoSQL database.
#Conclusion
TempData can be used to store data between two consecutive requests. This is a way to handle the Post/Redirect/Get scenario.
Here are some great resources:
Do you have a question or a suggestion about this post? Contact me!