Why to avoid TempData in Asp.Net MVC

Introduction

According to MSDN it “Represents a set of data that persists only from one request to the next.”

 It is a dictionary backed by the Session so every value which is added to TempData is added in the Session.

Added values are marked for deletion when they are read and when the request ends, the marked ones are deleted.

Reason for avoiding it

It writes session

TempData is backed by the Session and when the Session is written, it is(by default) locked for reading or writing. So in case there are several Ajax calls which have to read the Session and are supposed to run asynchronously, they are all waiting for the request which writes TempData to finish.

Adding of a load balacer

Additional attention is needed when load balancers are introduced and session needs to be saved not InProc but externally, in database or in third parties like Redis. All objects which are needed to be saved externally needs to be serializable so you need to check every object which is added in TempData in order to avoid serialization exceptions. This operation is cumbersome and can introduce instability in the application since you detect the exceptions only at run time.

Go Back functionality

Browser’s Go Back functionality could introduce bugs  – NullPointer Exceptions since data stored in TempData at one time, was removed from it. When GoBack button is pressed, browser executes again the previous requests so  additional functionality must be implemented in order to avoid exceptions, like checking every time if TempData is not null and if it then do some exceptional behavior.

A common best practice for using TempData is in Post-Redirect pattern but additional IsNull checking is needed.

Code Maintainability could be affected

TempData usage could be scattered all over the application so could be hard to maintain the code even if best practice is used- only in Post-Redirect pattern.

Alternative

Query string is a good alternative to TempData even if objects are needed to be transferred –by encoding them.

When object is encrypted the following steps are required:

  1. Encrypt the object
  2. Convert the encrypted byte array to a base64 string using Convert.ToBase64String(byteArray);
  3. Url encode the resulting string using HttpUtility.UrlEncode(base64String);

When the query string is decrypted the following steps are required:

  1. Execute the reverse base64 operation using Convert.FromBase64String(inputText);
  2. Decrypt the string resulted from the previous step.

Advantages

Session is not written so concurrent requests are not queued, all needed input is retrieved from the HTTP package.

If a load balancer is added, no object is needed to be serialized and also no changes are needed since no server state is used.

At “Go Back” functionality, since browser resends the request, it will resend also used query string so the functionality will not be affected.

Usage Exceptions

Usage exceptions could occur when sensitive data are needed to be transferred from one action to another and the encryption is not an alternative.

In Post-Redirect pattern when server validation fails (which in regular flow should never be the case since client validation should fail first) and the response should contain model errors, using TempData to store those server validation in order to be used in GET method, could be a straight forward path to take.

Another alternative

You can store data directly in Session BUT implement an IActionFilter to clear session data when needed. This  approach offers you a better management of when the values stored in session will be deleted.

This doesn’t offer the flexibility of using the query strings but it is a faster way to transmit data from one action to another.