Passing data between different controller action methods
Solution 1
HTTP and redirects
Let's first recap how ASP.NET MVC works:
- When an HTTP request comes in, it is matched against a set of routes. If a route matches the request, the controller action corresponding to the route will be invoked.
- Before invoking the action method, ASP.NET MVC performs model binding. Model binding is the process of mapping the content of the HTTP request, which is basically just text, to the strongly typed arguments of your action method
Let's also remind ourselves what a redirect is:
An HTTP redirect is a response that the webserver can send to the client, telling the client to look for the requested content under a different URL. The new URL is contained in a Location
header that the webserver returns to the client. In ASP.NET MVC, you do an HTTP redirect by returning a RedirectResult
from an action.
Passing data
If you were just passing simple values like strings and/or integers, you could pass them as query parameters in the URL in the Location
header. This is what would happen if you used something like
return RedirectToAction("ActionName", "Controller", new { arg = updatedResultsDocument });
as others have suggested
The reason that this will not work is that the XDocument
is a potentially very complex object. There is no straightforward way for the ASP.NET MVC framework to serialize the document into something that will fit in a URL and then model bind from the URL value back to your XDocument
action parameter.
In general, passing the document to the client in order for the client to pass it back to the server on the next request, is a very brittle procedure: it would require all sorts of serialisation and deserialisation and all sorts of things could go wrong. If the document is large, it might also be a substantial waste of bandwidth and might severely impact the performance of your application.
Instead, what you want to do is keep the document around on the server and pass an identifier back to the client. The client then passes the identifier along with the next request and the server retrieves the document using this identifier.
Storing data for retrieval on the next request
So, the question now becomes, where does the server store the document in the meantime? Well, that is for you to decide and the best choice will depend upon your particular scenario. If this document needs to be available in the long run, you may want to store it on disk or in a database. If it contains only transient information, keeping it in the webserver's memory, in the ASP.NET cache or the Session
(or TempData
, which is more or less the same as the Session
in the end) may be the right solution. Either way, you store the document under a key that will allow you to retrieve the document later:
int documentId = _myDocumentRepository.Save(updatedResultsDocument);
and then you return that key to the client:
return RedirectToAction("UpdateConfirmation", "ApplicationPoolController ", new { id = documentId });
When you want to retrieve the document, you simply fetch it based on the key:
public ActionResult UpdateConfirmation(int id)
{
XDocument doc = _myDocumentRepository.GetById(id);
ConfirmationModel model = new ConfirmationModel(doc);
return View(model);
}
Solution 2
Have you tried using ASP.NET MVC TempData ?
ASP.NET MVC TempData dictionary is used to share data between controller actions. The value of TempData persists until it is read or until the current user’s session times out. Persisting data in TempData is useful in scenarios such as redirection, when values are needed beyond a single request.
The code would be something like this:
[HttpPost]
public ActionResult ApplicationPoolsUpdate(ServiceViewModel viewModel)
{
XDocument updatedResultsDocument = myService.UpdateApplicationPools();
TempData["doc"] = updatedResultsDocument;
return RedirectToAction("UpdateConfirmation");
}
And in the ApplicationPoolController:
public ActionResult UpdateConfirmation()
{
if (TempData["doc"] != null)
{
XDocument updatedResultsDocument = (XDocument) TempData["doc"];
...
return View();
}
}
Solution 3
Personally I don't like to use TempData, but I prefer to pass a strongly typed object as explained in Passing Information Between Controllers in ASP.Net-MVC.
You should always find a way to make it explicit and expected.
Solution 4
I prefer to use this instead of TempData
public class Home1Controller : Controller
{
[HttpPost]
public ActionResult CheckBox(string date)
{
return RedirectToAction("ActionName", "Home2", new { Date =date });
}
}
and another controller Action
is
public class Home2Controller : Controller
{
[HttpPost]
Public ActionResult ActionName(string Date)
{
// do whatever with Date
return View();
}
}
it is too late but i hope to be helpful for any one in the future
Brendan Vogt
Wedding photographer and videographer from Paarl, South Africa. Join me on my new adventure in wedding photography and videography at Brendan Vogt Photo & Video.
Updated on July 05, 2022Comments
-
Brendan Vogt almost 2 years
I'm using
ASP.NET MVC 4
. I am trying to pass data from one controller to another controller. I'm not getting this right. I'm not sure if this is possible?Here is my source action method where I want to pass the data from:
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 } }
I need to pass it to this action method in this controller:
public class ApplicationPoolController : Controller { public ActionResult UpdateConfirmation(XDocument xDocument) { // Will add implementation code return View(); } }
I have tried the following in the
ApplicationPoolsUpdate
action method but it doesn't work:return RedirectToAction("UpdateConfirmation", "ApplicationPool", new { xDocument = updatedResultsDocument }); return RedirectToAction("UpdateConfirmation", new { controller = "ApplicationPool", xDocument = updatedResultsDocument });
How would I achieve this?
-
K D about 11 yearsdo you think it is worth to do like this? will it change the route values and loads correct view when you'll try return View() in UpdateConfirmation action?
-
jishnu saha about 11 yearsYes defiantly.Because if you call the UpdateConfirmation() then the returned view is based on "UpdateConfirmation" action, which is "/ApplicationPool/UpdateConfirmation" View.You should try this.I think it will work.
-
K D about 11 yearsIt won't. it will not change the route value dictionary value hence MVC will try to load view for the action which is performed first :)
-
jishnu saha about 11 yearsBut from the first action you return a view which contains the address of second view.So it will work.
-
Piotr Kula over 10 yearsTempData is purposely made to pass some simple data form one view controller to another without exposing all the data on the client URL or in the request. Its not ideal but its more efficient than Sessions. It handles ViewModels (or simple models) perfectly well. And is a handy feature to use.
-
Novox almost 10 yearsIt does not handle ViewData because ViewData is not Serializable, which is a requirement for sessions that can't be run in-process (web farm)... I greatly dislike TempData (is the nicest way I could put it).
-
GGleGrand over 8 yearsAm I correct that TempData is not safe for use across several load-balanced servers unless I also put a shared session cache under it?
-
Devsainii over 8 yearsThanks Rune. It's gud.
-
Blaise over 7 yearsI still believe we should by all means avoid using session, in this case ViewData. They are not typed, and works only in
In-proc
session mode. For any load balanced server that usesState Sever
orSql Server
session mode, the ViewData is lost. -
Blaise over 7 yearsBut in many cases, we want to pass a complex model in the
RedirectToAction
.