MVC-Pasar datos con RedirectToAction()


Me gustaría tomar los datos ingresados en un formulario de usuario MVC y mostrarlos en una vista diferente.

La clase tiene la siguiente variable privada:

IList<string> _pagecontent = new List<string>();

La siguiente acción acepta un objeto FormCollection, lo valida y lo pasa a la vista "Vista previa" como una Lista:

[Authorize(Roles = "Admins")]
[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateContent(FormCollection collection)
{
    if (ModelState.IsValid)
    {
        string PageToInsert = collection["PageToInsert"];
        string PageHeader = collection["PageHeader"];
        string PageBody = collection["PageBody"];

        //validate, excluded...

        _pagecontent.Add(PageToInsert);
        _pagecontent.Add(PageHeader);
        _pagecontent.Add(PageBody);

    }
    return RedirectToAction("Preview", _pagecontent);
}

La vista previa tiene la siguiente Directiva de página para pasar una Lista de objetos fuertemente tipeados:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Template.Master" Inherits="System.Web.Mvc.ViewPage<List<string>>" %>

Esperaría poder usar el objeto Modelo para obtener mis datos, pero por desgracia no. En la siguiente línea, obtengo una excepción error index out of bounds, indicando que el índice debe ser no negativo y menor que el tamaño de la colección:

<% if (Model[0].ToString() == "0") { %>

Y se han agregado algunos parámetros extraños a la URL, ya que resuelve: http://localhost:1894/Admin/Preview?Capacity=4&Count=3

Así que tengo dos preguntas:

  1. Cuando llamo a RedirectToAction y le paso mi Lista, ¿por qué es inaccesible en el objeto Modelo de la vista?
  2. ¿Cuál es la forma correcta de hacer lo que estoy tratando de hacer, es decir, pasar una colección de cadenas a una vista para mostrar allí?
Author: tereško, 2009-03-23

8 answers

Intente usar TempData. Es como un objeto de sesión de un solo disparo. Usted pone los valores que desea en TempData, inmediatamente redirigir y sacarlos. Hay una buena valoración crítica aquí: http://blogs.teamb.com/craigstuntz/2009/01/23/37947/

 55
Author: MichaelGG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-23 03:51:19

Tenga cuidado al usar TempData. Funciona muy bien en un entorno de servidor único, pero en un entorno de nube puede que no funcione como se espera, ya que no puede garantizar que la solicitud llegue a la misma máquina. Esto sucede porque TempData se basan en la asp.net sesión. Pero si está utilizando otro administrador de sesiones como SQL o AppFabric Cache, funcionará bien.

 11
Author: João Miguel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-25 19:24:21

El segundo parámetro para RedirectAction es routeValues, no model.

protected internal RedirectToRouteResult RedirectToAction(string actionName, object routeValues);

Intente usar TempData para el modelo. Es para la persistencia de datos entre redirecciones.

 7
Author: AndreasN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-23 21:43:23

El problema con RedirectToAction es que está devolviendo un HTTP 302 y el navegador entonces está en su propio ir y hacer una nueva solicitud HTTP. Es posible que desee considerar el uso de una cookie y/o un objeto de sesión para conservar los datos entre las solicitudes.

 4
Author: Chad Moran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-23 03:35:38

Esto no funciona porque RedirectToAction en realidad está enviando un Http 302 al navegador. Cuando el navegador recibe este 302, hace una nueva solicitud al servidor pidiendo la nueva página. Nueva solicitud, nuevas variables temporales.

También se enfrentará a este problema cuando intente guardar/editar/eliminar algo y por alguna razón lo niegue y tenga que devolver el formulario anterior nuevamente.

Entonces, en lugar de:

return RedirectToAction("Preview", _pagecontent);

Coloque la lógica de vista previa en un método separado y simplemente llame it:

return PreviewLogic(_pagecontent);

También puede usar el TempData[] dic para conservar los datos para la siguiente solicitud como otros han dicho, pero entonces no evitará el 302 viaje de ida y vuelta adicional al servidor.

 3
Author: andrecarlucci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-24 13:06:37

Suena como si estuvieras tratando de hacer:

public ActionResult UpdateContent(FormCollection form) {
    ...
    return View("Preview", _pagecontent);
}

Tenga en cuenta que una redirección se supone que es una "pizarra limpia" para el navegador (excepto por cosas como la cookie de autenticación). No puede decirle al navegador que pase información a la siguiente solicitud, ya que la siguiente solicitud debería poder mantenerse por sí sola. Todo lo que tienes que hacer es decirle al navegador qué URL solicitar a continuación. En ASP.NET MVC, cuando pasa un objeto arguments a RedirectToAction, las propiedades públicas de ese objeto se añaden como parámetros de cadena de consulta a la URL generada.

 2
Author: yfeldblum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-23 15:33:04

¿No puedes simplemente hacer 2 resultados de acción con el mismo nombre y marcar 1 de ellos con HttpPost?

    public ActionResult UpdateContent(FormCollection preview = null)
    {
        return View(preview);
    }
    [HttpPost]
    public ActionResult UpdateContent(FormCollection collection = null, bool preview = false)
    {
        if (preview)
            return UpdateContent(collection);
        else
            return UpdateContent(null);
    }
 0
Author: TeamEASI.com,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-05 17:36:19

Parece que está buscando el comando UpdateModel:

Echa un vistazo a la publicación de blog de ScottGu sobre el tema:

Métodos mejorados de UpdateModel y TryUpdateModel

 -3
Author: David P,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-23 14:59:52