TempData does not persist on pass to second action

505 Views Asked by At

I'm trying to pass TempData through a couple actions, but I can't get it to persist beyond one pass. I've read a ton of questions on StackOverflow about this, but I just can't get their solutions to work. I know TempData only persists for one redirect, but it is suggested that .Keep() or .Peek() should allow it to persist on another redirect. That unfortunately has not worked for me. I have also tried reassigning TempData and straight hard-coding of TempData from the second redirect and it still will not pass through. I'm obviously missing something. My code:

//First redirect
 public ActionResult Index(int? userId, int? reportingYear)
    {
        if (Session["State"] == null)
        {
            TempData["Timeout"] = "Your session has timed out. Please login to continue.";
            return RedirectToAction("LogOff", "Account");
        }
    }

//Second redirect
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public ActionResult LogOff()
    {
        //Delete the application cookie and clear session variables
        var cookies = Request.Cookies;
        List<string> tempCookies = new List<string>();

        foreach (string cookie in cookies)
        {
            if (cookie.ToString() != "quailCoord")
            {
                tempCookies.Add(cookie);
            };
        }

        foreach (string cookie in tempCookies)
        {
            HttpCookie deleteCookie = Request.Cookies[cookie];
            deleteCookie.Expires = DateTime.Now.AddDays(-1);
            Response.Cookies.Add(deleteCookie);
        }

        Session.Abandon();
        AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
        
        //When checking that the key exists, it does and enters the if statement to keep the data
        if (TempData.ContainsKey("Timeout")
        {
            TempData.Keep("Timeout");
        }
        return RedirectToAction("Login");
    }

//Third action
public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        //It does not find any TempData keys
        if (TempData.ContainsKey("Timeout"))
        {
            ViewBag.Timeout = TempData["Timeout"] as string;
        }
        return View();
    }

I have also attempted these in place of the TempData.Keep("Timeout") method:

TempData.Peek("Timeout")

TempData["Timeout"] = TempData["Timeout"]

TempData["Timeout"] = "Your session has timed out. Please login to continue."

None of these methods pass to the Login() action. TempData is always empty upon entering that action. When debugging, the minute I step over the return RedirectToAction("Login") line, the count in TempData turns to 0. What am I missing? Is deleting the cookies a problem?

1

There are 1 best solutions below

2
D-Shih On BEST ANSWER

Because TempData will store data in Session object which might store SessionId in cookie, if you delete that server will create another SessionId (object) for you instead of the original one.

so that if you want to keep TempData to multiple actions we might need to keep SessionId value from the cookie.

From your code, we can try to add a judgement to check cookie key whether if yes don't delete the cookie.

foreach (string cookie in cookies)
{
    if (cookie.ToString() != "quailCoord" && cookie.ToString() != "ASP.NET_SessionId")
    {
        tempCookies.Add(cookie);
    };
}