Pasar datos entre diferentes métodos de acción del controlador

Estoy usando ASP.NET MVC 4 . Estoy tratando de pasar datos de un controlador a otro controlador. No estoy haciendo esto bien. No estoy seguro si esto es posible?

Aquí está mi método de acción de origen donde quiero pasar los datos desde:

 public class ServerController : Controller { [HttpPost] public ActionResult ApplicationPoolsUpdate(ServiceViewModel viewModel) { XDocument updatedResultsDocument = myService.UpdateApplicationPools(); // Redirect to ApplicationPool controller and pass // updatedResultsDocument to be used in UpdateConfirmation action method } } 

Necesito pasarlo a este método de acción en este controlador:

 public class ApplicationPoolController : Controller { public ActionResult UpdateConfirmation(XDocument xDocument) { // Will add implementation code return View(); } } 

He intentado lo siguiente en el método de acción ApplicationPoolsUpdate pero no funciona:

 return RedirectToAction("UpdateConfirmation", "ApplicationPool", new { xDocument = updatedResultsDocument }); return RedirectToAction("UpdateConfirmation", new { controller = "ApplicationPool", xDocument = updatedResultsDocument }); 

¿Cómo lograría esto?

HTTP y redireccionamientos

Repasemos primero cómo funciona ASP.NET MVC:

  1. Cuando aparece una solicitud HTTP, se compara con un conjunto de rutas. Si una ruta coincide con la solicitud, se invocará la acción del controlador correspondiente a la ruta.
  2. Antes de invocar el método de acción, ASP.NET MVC realiza el enlace del modelo. El enlace de modelo es el proceso de asignar el contenido de la solicitud HTTP, que básicamente es solo texto, a los argumentos fuertemente tipados de su método de acción

Recordemos también qué es una redirección:

Una redirección HTTP es una respuesta que el servidor web puede enviar al cliente, diciéndole al cliente que busque el contenido solicitado bajo una URL diferente. La nueva URL está contenida en un encabezado de Location que el servidor web devuelve al cliente. En ASP.NET MVC, realiza un redireccionamiento de HTTP devolviendo un resultado de RedirectResult de una acción.

Pasar datos

Si acaba de pasar valores simples como cadenas y / o enteros, puede pasarlos como parámetros de consulta en la URL en el encabezado de la Location . Esto es lo que pasaría si usaras algo así como

 return RedirectToAction("ActionName", "Controller", new { arg = updatedResultsDocument }); 

como otros han sugerido

La razón por la que esto no funcionará es porque XDocument es un objeto potencialmente muy complejo. No existe una forma sencilla para que el marco MVC de ASP.NET serialice el documento en algo que se ajuste a una URL y luego XDocument el enlace del valor de la URL a su parámetro de acción XDocument .

En general, pasar el documento al cliente para que el cliente lo devuelva al servidor en la próxima solicitud, es un procedimiento muy frágil: requeriría todo tipo de serialización y deserialización y todo tipo de cosas podría salir mal. Si el documento es grande, también puede ser un desperdicio sustancial de ancho de banda y puede afectar gravemente el rendimiento de su aplicación.

En cambio, lo que desea hacer es mantener el documento en el servidor y pasarle un identificador al cliente. El cliente pasa el identificador junto con la siguiente solicitud y el servidor recupera el documento utilizando este identificador.

Almacenamiento de datos para su recuperación en la próxima solicitud

Entonces, la pregunta ahora es: ¿dónde guarda el servidor el documento mientras tanto? Bueno, eso es para que usted decida y la mejor opción dependerá de su situación particular. Si este documento necesita estar disponible a largo plazo, es posible que desee almacenarlo en el disco o en una base de datos. Si contiene solo información transitoria, mantenerla en la memoria del servidor web, en el caché ASP.NET o en la Session (o TempData , que es más o menos lo mismo que la Session al final) puede ser la solución adecuada. De cualquier forma, almacena el documento bajo una clave que le permitirá recuperar el documento más adelante:

 int documentId = _myDocumentRepository.Save(updatedResultsDocument); 

y luego devuelve esa clave al cliente:

 return RedirectToAction("UpdateConfirmation", "ApplicationPoolController ", new { id = documentId }); 

Cuando desee recuperar el documento, simplemente busquelo en función de la clave:

  public ActionResult UpdateConfirmation(int id) { XDocument doc = _myDocumentRepository.GetById(id); ConfirmationModel model = new ConfirmationModel(doc); return View(model); } 

¿Has probado usar ASP.NET MVC TempData ?

El diccionario ASP.NET MVC TempData se usa para compartir datos entre las acciones del controlador. El valor de TempData persiste hasta que se lee o hasta que finaliza la sesión del usuario actual. Los datos persistentes en TempData son útiles en escenarios como la redirección, cuando se necesitan valores más allá de una única solicitud.

El código sería algo como esto:

 [HttpPost] public ActionResult ApplicationPoolsUpdate(ServiceViewModel viewModel) { XDocument updatedResultsDocument = myService.UpdateApplicationPools(); TempData["doc"] = updatedResultsDocument; return RedirectToAction("UpdateConfirmation"); } 

Y en ApplicationPoolController:

 public ActionResult UpdateConfirmation() { if (TempData["doc"] != null) { XDocument updatedResultsDocument = (XDocument) TempData["doc"]; ... return View(); } } 

Personalmente, no me gusta usar TempData, pero prefiero pasar un objeto fuertemente tipado como se explica en Pasando información entre controladores en ASP.Net-MVC .

Siempre debe encontrar la forma de hacerlo explícito y esperado.

prefiero usar esto en lugar de TempData

 public class Home1Controller : Controller { [HttpPost] public ActionResult CheckBox(string date) { return RedirectToAction("ActionName", "Home2", new { Date =date }); } } 

y otra controller Action es

 public class Home2Controller : Controller { [HttpPost] Public ActionResult ActionName(string Date) { // do whatever with Date return View(); } } 

es demasiado tarde, pero espero ser útil para cualquiera en el futuro

Si necesita pasar datos de un controlador a otro, debe pasar datos por valores de ruta. Porque ambos son solicitudes diferentes. Si envía datos de una página a otra, entonces tiene que consultar cadena de usuario (lo mismo que valores de ruta).

Pero puedes hacer un truco:

En su acción de llamada, llame a la acción llamada como un método simple:

 public class ServerController : Controller { [HttpPost] public ActionResult ApplicationPoolsUpdate(ServiceViewModel viewModel) { XDocument updatedResultsDocument = myService.UpdateApplicationPools(); ApplicationPoolController pool=new ApplicationPoolController(); //make an object of ApplicationPoolController class. return pool.UpdateConfirmation(updatedResultsDocument); // call the ActionMethod you want as a simple method and pass the model as an argument. // Redirect to ApplicationPool controller and pass // updatedResultsDocument to be used in UpdateConfirmation action method } }