Passing data between different controller action methods

264,924

Solution 1

HTTP and redirects

Let's first recap how ASP.NET MVC works:

  1. 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.
  2. 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

Share:
264,924
Brendan Vogt
Author by

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, 2022

Comments

  • Brendan Vogt
    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
    K D about 11 years
    do 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
    jishnu saha about 11 years
    Yes 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
    K D about 11 years
    It 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
    jishnu saha about 11 years
    But from the first action you return a view which contains the address of second view.So it will work.
  • Piotr Kula
    Piotr Kula over 10 years
    TempData 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
    Novox almost 10 years
    It 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
    GGleGrand over 8 years
    Am 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
    Devsainii over 8 years
    Thanks Rune. It's gud.
  • Blaise
    Blaise over 7 years
    I 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 uses State Sever or Sql Server session mode, the ViewData is lost.
  • Blaise
    Blaise over 7 years
    But in many cases, we want to pass a complex model in the RedirectToAction.