Passing a model object to a RedirectToAction witho

2019-03-25 19:54发布

问题:

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?

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


回答2:

The quick answer is don't pass the entire model but some identifier that you can use to retrieve the model from the repository:

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

        return RedirectToAction("Gracias", model.ID);
    }

    return View(model);
}

public ActionResult Gracias(int contactID)
{
    ContactModel model = new ContractRepository().GetContact(contactID);
    return View(model);
}


回答3:

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?



回答4:

Couldn't this be easily done without a Redirect?

Here's what i have:

    [HttpGet]
    public ActionResult Contact()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Contact(EmailResponse response)
    {
        if(ModelState.IsValid){
            return View("Thanks", response);
        }
        else
        {
            return View();
        }
    }

The "Thanks" view is strongly typed to EmailResponse