2008-08-05 29 views
113

Al usar ASP.NET MVC hay situaciones (como el envío de formularios) que pueden requerir un RedirectToAction.Cómo redireccionar aAction en ASP.NET MVC sin perder los datos de solicitud

Una de estas situaciones es cuando encuentra errores de validación después de enviar un formulario y necesita redireccionar al formulario, pero desea que el URL refleje el URL del formulario, no la página de acciones a la que envía.

Como requiero que el formulario contenga los datos ed originalmente POST, para conveniencia del usuario, así como también con fines de validación, ¿cómo puedo pasar los datos a través del RedirectToAction()? Si utilizo el parámetro viewData, mis parámetros POST se cambiarán a los parámetros GET.

+0

He aquí una pregunta que es similar (sobre el mismo tema), pero diferente a este. De todos modos, todavía puede ser de interés para los interesados ​​en esta pregunta: [http://stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get](http:/ /stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get) –

+0

¿Por qué no devuelve la misma vista si hay un error? RedirectToAction generalmente se llama si el Modelo es válido, ¿o me falta algo? – niico

Respuesta

76

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 de "forma" se 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); 
} 
+1

RedirectToAction (a => a.Form()) no compila para mí usando MVCv2, ¿está utilizando MVCv3? – ChrisAnnODell

+1

Esto fue antes de MVC1 (2008). Las lambdas fueron eliminadas en algún momento, creo (hay un proyecto codeplex MVCContrib que las reintroduce, aunque también puede usar su atributo de ayuda en esa etapa: http: // stackoverflow.com/questions/1936/how-to-redirecttoaction-in-asp-net-mvc-without-losing-request-data/718653 # 718653). En mvc2 debería poder ir a RedirectToAction ("Formulario"), es decir, el nombre como una cadena, aunque recuerdo vagamente que MVC 2 o 3 introdujo un atributo de ayuda similar al de MVCContrib si está interesado en buscar. –

36

Tenga en cuenta que las tiendas de cobro TempData la forma en la sesión. Si no le gusta ese comportamiento, puede implementar la nueva interfaz ITempDataProvider y utilizar algún otro mecanismo para almacenar datos temporales. No lo haría a menos que supiera con certeza (a través de la medición y el perfil) que el uso del estado de sesión lo está perjudicando.

8

Hay otra manera de evitar tempdata. El patrón que me gusta incluye la creación de 1 acción tanto para el render original como para la renderización de la forma no válida. Es algo como 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 rellenará con valores anteriores) y mostrar los mensajes de error.

Cuando la publicación de esta acción, si es válida, transfiere el control a otra acción.

Estoy tratando de hacer que este patrón sea fácil en el .net validation framework mientras construimos el soporte para MVC.

+0

Cool. Parece que alguien notó esta idea básica con la vista previa 5 también. –

+0

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 la confirmación "¿Desea volver a enviar los datos del formulario?". Usar la solución TempData como dice MattMitchell elimina este problema. – user10479

13

Tome un vistazo a MVCContrib, usted puede hacer esto:

using MvcContrib.Filters; 

[ModelStateToTempData] 
public class MyController : Controller { 
    // 
    ... 
} 
2

Si desea pasar los datos a la acción reorientada, el método se puede usar es:

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