TempData Not Being Cleared
Asked Answered
C

4

9

I'm working on an ASP.NET MVC 3 web application, where i use TempData to store a model object, in the scenario where the user is not logged in.

Here's the flow:

  1. Use submits form.
  2. Code (special action filter) adds model to TempData , redirects to logon page.
  3. User redirected back to GET action, which reads TempData and calls POST action directly

After step 3, i would have thought TempData would be cleared?

Here's the code:

[HttpGet]
public ActionResult Foo()
{
    var prefilled = TempData["xxxx"] as MyModel;
    if (prefilled != null)
    {
       return Foo(prefilled);
    }
}

[HttpPost]
[StatefulAuthorize] // handles the tempdata storage and redirect to logon page
public ActionResult Foo(MyModel model)
{
   // saves to db.. etc
}

I found this article which states:

  1. Items are only removed from TempData at the end of a request if they have been tagged for removal.
  2. Items are only tagged for removal when they are read.
  3. Items may be untagged by calling TempData.Keep(key).
  4. RedirectResult and RedirectToRouteResult always calls TempData.Keep().

Well by reading it with TempData["xxx"] isn't that a "read" and therefore they should be tagged for removal?

And the last one concerns me a bit - since i'm doing a Redirect after the POST (P-R-G). But this can't be avoided.

Is there a way i can say "ditch this item". TempData.Remove ? Or am i doing this wrong?

Condensate answered 3/10, 2011 at 2:57 Comment(4)
You need to do a full redirect and not return a second action method. That's why it's not working.Scape
@BuildStarted - but the POST method does do a redirect after it's finished. You can't do a redirect to a POST method, won't that be a GET?Condensate
Well, from what I'm reading based on the limited data is that you're doing a get and redirection in code to a post - that StatefulAuthorize won't be called.Scape
@BuildStarted - the StatefulAuthorize is called in the initial POST, e.g when the user is unauthenticated and tries to submit the form. I don't want (nor expect it) to get called when i invoke the method manually. Anyway, Darin has summed up my problem. Bottom line - i dont think i should be using TempData, i should be using Session.Condensate
C
13

Fixed by adding TempData.Remove right after i read it.

Not really happy about this. I thought the whole point of TempData was that i didn't have to do this.

May as well be using Session directly.

Condensate answered 3/10, 2011 at 3:5 Comment(1)
That's not the way to clear it off. You could have pretty much used Session instead of TempData. Only advantage with TempData is that it manages the data by itself. As I had answered earlier, Value is only cleared when the Action results in a 200 (Such as ViewResult/ContentResult/JsonResult) in all other scenarios, precisely any actions resulting Http Status code of 302(such as RedirectAction )will retain the data in TempData. Read through the following for more details #32572099Leeds
Z
7

There are 2 GET HTTP requests involved here:

  1. The first request is sent by the client and is the one which stores something into TempData
  2. At the end of the first request the client sends a second HTTP request to fetch the logon page.

There is no POST request involved in your scenario. The fact that from your GET Foo action you are invoking the POST Foo action doesn't mean that there is a separate request being performed (you are still in the context of the initial GET request). It is only a C# method call, not a separate request.

You store something into TempData during the first request and this TempData will be available for the second one. So it will be available in the controller action rendering the logon page.

So you must read from TempData in action rendering the logon page if you want TempData to be removed.

Zoolatry answered 3/10, 2011 at 6:2 Comment(1)
Your right. But i don't care about it on the logon page. I'm trying to do an "auto post" when they sign in, so they don't have to re-submit the form. That's why im "calling" my POST action directly (i know it's not a seperate request). So i guess i shouldn't really be using TempData, since it's 2 requests later for which i need the data, not the next one.Condensate
L
7

Below are some of the key points to note when using Temp data.

1) A read access to temp data doesn't remove items from the dictionary immediately, but only marks for deletion.

2) Temp data will not always remove the item that has been accessed. It only removes the item when an action results in an Http 200 status code (ViewResult/JsonResult/ContentResult etc).

3) In case of actions that result in an Http 302 (such as any redirect actions), the data is retained in storage even when it is accessed.

Leeds answered 16/5, 2015 at 1:22 Comment(1)
Referring to point number 3. What is the best place to clear this temp data when I do a redirect.Bozarth
L
0

That's not the way to clear it off. You could have pretty much used Session instead of TempData. Only advantage with TempData is that it manages the data by itself.

As I had answered earlier, Value is only cleared when the Action results in a 200 (Such as ViewResult/ContentResult/JsonResult) in all other scenarios, precisely any actions resulting Http Status code of 302(such as RedirectAction )will retain the data in TempData.

Read through the following for more details

ASP.NET TempData isn't cleared even after reading it

Leeds answered 14/9, 2015 at 18:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.