Cómo redirigir a acción en ASP.NET MVC sin perder los datos de la solicitud

123

Usando ASP.NET MVC hay situaciones (como el envío de formularios) que pueden requerir a RedirectToAction.

Una de esas situaciones es cuando encuentra errores de validación después de enviar un formulario y necesita redirigir de nuevo al formulario, pero desea que la URL refleje la URL del formulario, no la página de acción a la que se envía.

Como necesito que el formulario contenga los POSTdatos editados originalmente , para conveniencia del usuario, así como para fines de validación, ¿cómo puedo pasar los datos a través del RedirectToAction()? Si uso el parámetro viewData, mis POSTparámetros se cambiarán a GETparámetros.

Matt Mitchell
fuente
Aquí hay una pregunta que es similar (sobre el mismo tema), pero diferente a esta. De todos modos, aún puede ser de interés para aquellos interesados ​​en esta pregunta: http://stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get
Chris Pietschmann
¿Por qué no estás devolviendo la misma vista si hay un error? Se suele llamar a RedirectToAction si el modelo es válido, ¿o me falta algo?
niico

Respuestas:

81

La solución es utilizar la propiedad TempData para almacenar los componentes de solicitud deseados.

Por ejemplo:

public ActionResult Send()
{
    TempData["form"] = Request.Form;
    return this.RedirectToAction(a => a.Form());
}

Luego, en su acción "Formulario" puede ir:

public ActionResult Form()
{
    /* Declare viewData etc. */

    if (TempData["form"] != null)
    {
        /* Cast TempData["form"] to 
        System.Collections.Specialized.NameValueCollection 
        and use it */
    }

    return View("Form", viewData);
}
Matt Mitchell
fuente
1
RedirectToAction (a => a.Form ()) no se compila para mí usando MVCv2, ¿estás usando MVCv3?
ChrisAnnODell
1
Esto fue anterior a MVC1 (2008). Las lambdas se eliminaron en algún momento, creo (hay un proyecto codeplex MVCContrib que las reintroduce, aunque también puede usar su atributo auxiliar en esa etapa: stackoverflow.com/questions/1936/… ). En mvc2, debería poder ir a RedirectToAction ("Formulario"), es decir, nombrar como una cadena, aunque recuerdo que MVC 2 o 3 introdujo un atributo auxiliar similar al de MVCContrib si está interesado en buscar.
Matt Mitchell, el
37

Tenga en cuenta que TempData almacena la colección de formularios en sesión. Si no le gusta ese comportamiento, puede implementar la nueva interfaz ITempDataProvider y usar algún otro mecanismo para almacenar datos temporales. No haría eso a menos que sepa de hecho (a través de la medición y el perfil) que el uso del estado de sesión lo está perjudicando.

Hackeado
fuente
13

Echa un vistazo a MVCContrib , puedes hacer esto:

using MvcContrib.Filters;

[ModelStateToTempData]
public class MyController : Controller {
    //
    ...
}
Dan
fuente
8

Hay otra forma de evitar tempdata. El patrón que me gusta implica crear 1 acción tanto para el renderizado original como para el renderizado inválido. Es algo parecido a esto:

var form = new FooForm();

if (request.UrlReferrer == request.Url)
{
     // Fill form with previous request's data
}

if (Request.IsPost())
{
     if (!form.IsValid)
     {
         ViewData["ValidationErrors"] = ...
     } else {
         // update model
         model.something = foo.something;
         // handoff to post update action
         return RedirectToAction("ModelUpdated", ... etc);
     }
}

// By default render 1 view until form is a valid post
ViewData["Form"] = form;
return View();

Ese es el patrón más o menos. Un pequeño pseudoy. Con esto, puede crear 1 vista para manejar la representación del formulario, volver a mostrar los valores (ya que el formulario se completará con valores anteriores) y mostrar mensajes de error.

Cuando se publica en esta acción, si es válida, transfiere el control a otra acción.

Estoy tratando de facilitar este patrón en el marco de validación .net a medida que desarrollamos soporte para MVC.

Dane O'Connor
fuente
También uso TempData, el problema tal como lo entiendo, con su solución, Deeno es que si el usuario actualizara la página después de publicar datos no válidos, recibiría una confirmación de "¿Desea volver a enviar los datos del formulario?". Usar la solución TempData como dice MattMitchell elimina este problema.
user10479
Frio. Parece que alguien notó esta idea básica con la vista previa 5 también.
Matt Mitchell
2

Si desea pasar datos a la acción redirigida, el método que podría usar es:

return RedirectToAction("ModelUpdated", new {id = 1});
// The definition of the action method like  public ActionResult ModelUpdated(int id);
lzlstyle
fuente
0

TempData es la solución que mantiene los datos de acción en acción.

Employee employee = new Employee
                {
                        EmpID = "121",
                        EmpFirstName = "Imran",
                        EmpLastName = "Ghani"
                };
                TempData["Employee"] = employee;
Aswal
fuente