The MVC framework – the TempData property
As we’ve seen in the last post of the series, the MVC platform introduced the notion of “request associated data” by creating the TempDataDictionary which can be accessed through the Controller’s TempData property. As we’ve discussed, the data you put in that dictionary will only “survive” a single request. What this means is that the data you add to the dictionary will only be there on the second request that comes in after it was added to the dictionary. It’s not there on the third! Here’s an example that might explain how it works:
- You add some info to the TempData property of your controller;
- The controller finishes its processing and sends back the response (recall from the previous post that at the end of the processing the TempData dictionary is persisted by the current TempData provider);
- A new request is processed by a controller (doesn’t have to be the same controller that was responsible for setting the TempData) and the TempData is recovered by the current provider.
- This request ends and TempData is saved. It’s important to understand that only those items that have been “changed” (or “touched”) will be saved. For instance, if during the 1st processing you add two elements to the TempData and then, on the 2nd, you change the values of only one of those entries, then only that item will be available on the third request!
As you can see, this “protocol” is really cool for keeping values that you might need on a second request. Generally, you’ll see lots of examples where TempData is used to keep info you’re putting on a form so that you can recover it quickly on a second request if the user has introduced incorrect data. In my experiences, I’ve noticed that TempData is also cool for:
- pagination: suppose you have a search page and you only want to show x items at once. You can use TempData to save the search words while the user goes through all the pages;
- passing data between controllers: this works really well when you’re redirecting from one controller to another and you need to pass out-of-band information.
I’m sure that there might be quite some more uses for it, but these are two I’ve used with success in the recent past (ok, ok, I admit it! In these last 2/3 weeks :) ).
As you might expect from such a modular platform, the TempDataDictionary isn’t really be responsible for saving/loading those dirty entries (though it does expose the expected Load and Save methods in preview 4). That work is done by a type that implements the ITempDataProvider interface. Currently, this interface defines the following contract:
public interface ITempDataProvider
void SaveTempData(TempDataDictionary tempDataDictionary);
The preview 4 of the ASP.NET MVC platform defines a single ITempDataProvider: the SessionStateTempDataProvider class. This is really a simple class. The only thing it does is add an entry to the session (named __ControllerTempData) which points to the TempDataDictionary maintained on the TempData property of the controller.
In practice, this means that if you want to use this property you must ensure that you’ve enabled session state (by default, the MvcHandler does that; so, if you’re creating your own handler and you want to reuse the “Controller logic”, don’t forget to add the IRequiresSessionState interface to your handler). As you might also expect, if you change the default session provider, you might need to garantee that the items you’re adding to the TempDataDictionary are serializable.
If you really don’t want to rely on session state, you can also implement your own temp data serializer by implementing the ITempDataProvider interface. After doing that, just pass an instance of that type to the TempDataProvider property of your controller.
Before ending the post, I’d like to point you to one custom error that I’ve seen pop up once or twice on the MVC forums. The dreaded “The provider requires SessionState to be enabled”. Ok, if you’re developing a custom HTTP handler, this means that you’ve forgot to add the IRequiresSessionState interface to the implementation list of your class.
What might be more intriguing is getting this error without using a custom HTTP handler. For instance, look at this example…As you can see, the problem is that he was trying to use a singleton controller and that would really break everything up! As you can see, there are really several things which might lead you to a session error…
On the next posts, I’ll keep talking about the MVC framework. Keep tuned!