kubi
kubi

Reputation: 947

Using TempData dictionary prevents RedirectToAction from working

I want to add view model to TempData in order to pass it to another controller like this (referring to last 2 lines):

[HttpPost("register")]
public async Task<IActionResult> Register(RegisterViewModel rvm)
{
    if (ModelState.IsValid)
    {
        var result = await _authManager.RegisterUserAsync(rvm.FullName, rvm.Email, rvm.Password);

        if (result.IsSuccessful)
        {
            return RedirectToAction("Login", "Home", new { message = result.Message });
        }
        else
        {
            TempData["rvm"] = rvm;
            return RedirectToAction("Register", "Home");
        }
    }

    TempData["rvm"] = rvm;
    return RedirectToAction("Register", "Home");
}

The problem is that, after performing this operation, the RedirectToAction method doesn't actually work and I'm being left with a blank page (the url also doesn't change). I add that, without the TempData line, everything works fine.

Any suggestions what am I dong wrong here?

EDIT:

Home/Register

[HttpGet("register")]
public IActionResult Register()
{
    RegisterViewModel rvm = (RegisterViewModel)TempData["rvm"];
    return View(rvm);
}

Upvotes: 2

Views: 1945

Answers (2)

Shyju
Shyju

Reputation: 218702

This is by design. In Asp.Net core, you cannot pass complex types in TempData. You can pass simple types like string, int, Guid etc.

If you absolutely want to pass a complex type object via TempData, you have 2 options.

1) Serialize your object to a string and pass that.

Here is a sample using Json.NET to serialize the object to a string

var s = Newtonsoft.Json.JsonConvert.SerializeObject(rvm);
TempData["rvm"] = s;
return RedirectToAction("About", "Home");

Now in your About action method, read this value from the TempData and deserialize it to your RegisterViewModel class object.

public IActionResult About()
{
   if (TempData["rvm"] is string s)
   {
       var rvm = JsonConvert.DeserializeObject<RegisterViewModel>(s);
       // use rvm now
   }
   // to do : return something
}

2) Set a dictionary of simple types to TempData

var d = new Dictionary<string, string>
{
    ["FullName"] = rvm.FullName,
    ["Email"] = rvm.Email;
};
TempData["MyModelDict"] = d;
return RedirectToAction("About", "Home");

and read it later

public IActionResult About()
{
   if (TempData["MyModelDict"] is Dictionary<string,string> dict)
   {
      var name = dict["Name"];
      var email =  dict["Email"];
   }
   // to do : return something
}

Upvotes: 3

objectively C
objectively C

Reputation: 998

It is not much of an answer, but I experienced the same issue with no resolution. I changed tempdata to a Session["rvm"] variable and was successful. Consider pivoting from tempdata to Session.

Upvotes: 0

Related Questions