Using TempData dictionary prevents RedirectToActio

2019-05-27 04:26发布

问题:

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);
}

回答1:

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.



回答2:

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
}