Passing a model object to a RedirectToAction without polluting the URL?

20,660

Solution 1

Sounds like a solution for TempData!

[HttpPost]
public ActionResult Index(ContactModel model)
{
  if (ModelState.IsValid)
  {
    // Send email using Model information.
    TempData["model"] = model;
    return RedirectToAction("Gracias");
  }

  return View(model);
}

public ActionResult Gracias()
{
  ContactModel model = (ContactModel)TempData["model"];
  return View(model);
}

Solution 2

Instead of doing

return RedirectToAction("Gracias", model);

You could do

[HttpPost]
public ActionResult Index(ContactModel model)
{
    if (ModelState.IsValid)
    {
        // Send email using Model information.

        return View("Gracias", model);
    }

    return View(model);
}

and remove your Gracias controller action. Using above the "Gracias" view will be displayed with your ContactModel model.

I don't see the need to have a separate controller action if it uses the same model and is a lock step part of the workflow ex. "a successful POST to Index will always result in the Gracias View being displayed"

You could also store the model in TempData (which is like a 1 request session state) but I don't see any point in doing that in your situation as it just complicates things

Thoughts?

Share:
20,660
sergserg
Author by

sergserg

sergserg

Updated on July 05, 2022

Comments

  • sergserg
    sergserg almost 2 years

    Here's what I'm trying to do:

    public ActionResult Index()
    {
        return View();
    }
    
    [HttpPost]
    public ActionResult Index(ContactModel model)
    {
        if (ModelState.IsValid)
        {
            // Send email using Model information.
    
            return RedirectToAction("Gracias", model);
        }
    
        return View(model);
    }
    
    public ActionResult Gracias(ContactModel model)
    {
        return View(model);
    }
    

    All three action methods are in the same controller. Basically, a user type up some data in the contact form and I want to redirect them to a thank you page using their name in the Model object.

    As the code is, it works, but the URL passed along with GET variables. Not ideal.

    http://localhost:7807/Contacto/Gracias?Nombre=Sergio&Apellidos=Tapia&Correo=opiasdf&Telefono=oinqwef&Direccion=oinqef&Pais=oinqwef&Mensaje=oinqwef
    

    Any suggestions?

  • sergserg
    sergserg over 11 years
    I had no idea you could save complex types to the TempData dictionary. TIL. Thanks!
  • Erik Philips
    Erik Philips over 11 years
    Only as long as they are Serializable!! TempData is stored in session, which only allows Serializable objects/classes.
  • Erik Philips
    Erik Philips over 11 years
    The url would look like http://localhost:7807/Contacto/Index, if that is acceptable, this is the easiest way.
  • John Culviner
    John Culviner over 11 years
    Temp data could certainly work here but why not just display the "Gracias" view directly from Index (where the model is already in scope). You also save your self a server round trip that is essentially a useless redirect.
  • Erik Philips
    Erik Philips over 11 years
    First, the OP asked how to use RedirectToAction. Secondly, as I mentioned on your answer, the URL would not be /Gracias, but /Index so it depends on what the OP wants the url to look like.
  • John Culviner
    John Culviner over 11 years
    Good point I hadn't thought about the URL displayed really mattering. If it does then TempData is the best solution
  • sergserg
    sergserg over 11 years
    Yeah that's not acceptable that's why I didn't go this route.
  • John Culviner
    John Culviner over 11 years
    Now just hope someone doesn't hit "localhost:7807/Contacto/Gracias" at some other time (or if they hit the back button and the page isn't cached) because the will come back with a view with empty fields and possibly even an exception depending on what your view looks like. Considering that you might not really want another URL being displayed.
  • sergserg
    sergserg over 11 years
    I'll just check if the TempData is empty and redirect if so.
  • Erik Philips
    Erik Philips over 9 years
    This doesn't work the way you think it does. If I pass in a updated model in the HttpPost Index() method, all those changes are lost because all the values in the method Gracias() are from the database, not the user.