3

I understand that TempData is designed to work only between a single page request. But I think have a situation I think breaks the intended functionality.

I use Controllers in preference to Handlers for delivering images. I don't now if that is best practice, but it works very well for me. The problem though, is that each call to one of the image Actions obviously uses up a TempData credit.

Is there a way in MVC to say "This Controller/Action is out of the scope of normal page requests" and therefore either persist the TempData or remove itself from the TempData life cycle completely?

Rich

kim3er
  • 6,306
  • 4
  • 41
  • 69
  • You're almost certainly misusing TempData. TempData is for redirects only. If you use it for a redirect, the images won't be a problem, because the HTML request *must* precede the image requests. Because you say that the image requests *do* interfere with TempData, I conclude that you are using it outside the context of a redirect. See http://blogs.teamb.com/craigstuntz/2009/01/23/37947/ for a fuller explanation. – Craig Stuntz Nov 03 '09 at 15:37
  • Thanks for the reply. You are correct in that I am not using TempData in a redirect, but I don't agree that TempData is for redirects only. I am quite happy to be proven wrong, but I am using TempData to pass data between a same page post. I do not want to use ViewData as I don't won't to embed the information into the HTML. – kim3er Nov 03 '09 at 16:17
  • That is your problem, then. One piece of evidence for what I say above is the fact that what you are presently doing doesn't work. Only in the case of a redirect do you have *any* certainty of what the "next" request will be. The only reliable fix will be to use TempData correctly. – Craig Stuntz Nov 03 '09 at 17:20
  • Correct me if I'm wrong but the Redirect theory is only your interpretation, I've not managed to find any documentation to support this. I accept that restricting TempData's use to Redirects would prevent the sort of conflicts we're discussing, but proper testing can also protect you. Anyway, thank you for your input. – kim3er Nov 03 '09 at 21:22
  • Aside from the fact that *TempData simply does not work* for any other purpose, I have discussed this privately with a member of the MVC team, after I proposed renaming TempData to RedirectData during the original MVC beta. (The response was essentially, "That's a better name, but it's too late in the beta cycle to ship a breaking change like that.") – Craig Stuntz Nov 04 '09 at 01:01

3 Answers3

3

My solution has been to create an Attribute that persists the TempData across page requests. My initial reaction to this is "yuck", but I want to effectively exclude any controllers decorated with the Attribute from the TempData lifecycle.

using System.Web.Mvc;

namespace K3R.Web.Mvc.Filters {
    public sealed class PersistTempDataAttribute : ActionFilterAttribute {
        public PersistTempDataAttribute() { }

        public override void OnActionExecuting(ActionExecutingContext filterContext) {
            var tempData = filterContext.Controller.TempData;
            if (tempData == null || tempData.Count == 0)
                return;

            string[] keys = new string[tempData.Keys.Count];
            tempData.Keys.CopyTo(keys, 0);
            foreach (var key in keys)
                tempData[key] = tempData[key];
        }
    }
}

Any feedback on a better solution would be appreciated.

Rich

kim3er
  • 6,306
  • 4
  • 41
  • 69
  • I don't think completely exclude a controller form the lifecycle is possible. You can apply your PersistTempDataAttribute either on the whole Controller or on a single Method. Remember that the "OnActionExecuting" method is executed >before< your actual function and the "OnActionExecuted" methid is executed >after< your function. However, storing Information beyond a single request should better be stored in a database or any other caching system. – Sebastian Nov 03 '09 at 14:24
  • Absolutely, I completely agree. I just didn't want to upset existing code that uses TempData with the inclusion of the Images Controller. I concede that using a separate Controller to delivery auxiliary items like images is probably not the best option in this scenario. – kim3er Nov 03 '09 at 15:56
  • 1
    It looks like MVC2 has now changed the way TempData to works. It now persists until the data is used. – kim3er Mar 10 '10 at 12:30
0

I'm not sure of the exact answer to this as I'm pretty new to MVC myself. However, I have heard of people having trouble with AJAX requests killing off the TempData before they wanted it to as well.

I guess you could implement your own Session based system to store this information?

I'm sure someone else will have a more complete answer for you soon, though!

Chris Roberts
  • 18,622
  • 12
  • 60
  • 67
  • I'm adding Image Controllers to a workflow that already uses TempData, I'd prefer not to rock the boat. For this reason, I'm working on an attribute which persists TempData. I know this goes against the purpose of TempData, but I view these Helper Controllers as special cases. Thanks for your help. – kim3er Nov 03 '09 at 13:12
-1

I do not completely understand your way of doing it and why but I would rather go with handlers. Or if you stick to controller actions, I can say that this worked for me fine without any issues for delivering images on-the-fly and I used FileContentResult in my controller actions.

Like this:

        return File(imageBytes, imageType);

You get the bytes out of datastore or somewhere..

hope it helps

mare
  • 13,033
  • 24
  • 102
  • 191