At times you need to pass data from an action method belonging to one controller to an action method belonging to another controller. There are three ways to accomplish this task. They are:
- Pass data as query string parameters
- Pass data in TempData dictionary
- Pass data as route parameters
Let's quickly see how each of these three approaches work.
Pass data as query string parameters
This approach is possibly the most primitive one and involves no special consideration from your side. The action method sending the data can use Redirect() method or RedirectToAction() method to transfer the control to the receiving action method. The following code shows how this is done:
public ActionResult Index()
{
Customer data = new Customer()
{
CustomerID = 1,
CustomerName = "Abcd",
Country = "USA"
};
string url=string.Format("/home2/index?customerid={0}
&customername={1}&country={2}",
data.CustomerID,data.CustomerName,data.Country);
return Redirect(url);
}
The above code shows Index() action from Home1 controller. The Index action method instantiates Customer object - the model class - that looks like this:
public class Customer
{
public int CustomerID { get; set; }
public string CustomerName { get; set; }
public string Country { get; set; }
}
It then forms a URL pointing to the Index() action from Home2 controller. Notice how data from Customer object is transferred in the form of query string parameters. In the above example there is no logic for generating model data but in a more realistic case you may have such a logic in this method. And once the data is generated you can pass it to the another controller using query string. The Redirect() method then takes the control to the Index() action of Home2 controller.
The Index() action of Home2 can receive the data as shown below:
public ActionResult Index()
{
Customer data = new Customer();
data.CustomerID = int.Parse(Request.QueryString["CustomerID"]);
data.CustomerName = Request.QueryString["CustomerName"];
data.Country = Request.QueryString["Country"];
return View(data);
}
As you can see Request.QueryString collection is being used to read the values passed in the query string. Once a Customer object is formed, it is passed to the Index view.
This technique has an advantage that it is quite simple and requires no additional configuration. However, it's bit crude technique and you should avoid it if any of the other techniques can be used.
Pass data using TempData dictionary
In this technique you store the data to be passed in the TempData dictionary in the sender action method. The receiving action method reads the data from the TempData dictionary. You might be aware that TempData dictionary can hold data till it is read and this can carry data across multiple requests. The following code shows how this is done:
public ActionResult Index()
{
Customer data = new Customer()
{
CustomerID = 1,
CustomerName = "Abcd",
Country = "USA"
};
TempData["mydata"] = data;
return RedirectToAction("Index", "Home2");
}
As you can see Index() action instantiates a Customer object as before. This time, however, it stores the Customer object in a TempData key named mydata. The RedirectToAction() method is then used to take the control to the Index() action of Home2 controller.
Inside the Index() of Home2, you can read the value as follows:
public ActionResult Index()
{
Customer data = TempData["mydata"] as Customer;
return View(data);
}
The above code reads the Customer object from TempData dictionary and passes it to the Index view.
The TempData technique doesn't require any additional setup but it requires that session state be enabled. Also, TempData is designed to store arbitrary pieces of data. If you are planning to send model objects through TempData, that may be a deviation from standard design practices.
Pass data as route parameters
In this technique you need to do an additional work of defining a route in the system. For example, if you wish to pass the Customer data in the form of route parameters you need to define a route like this:
routes.MapRoute(
name: "Default2",
url: "{controller}/{action}/
{customerid}/{customername}/{country}",
defaults: new { controller = "Home2", action = "Index" }
);
As shown above, the route includes {customerid}, {customername}, and {country} route parameters and the route is mapped with Index() action of Home2 controller. Once the above configuration is done you can pass data from the sender action as follows:
public ActionResult Index1()
{
Customer data = new Customer()
{
CustomerID = 1,
CustomerName = "Abcd",
Country = "USA"
};
return RedirectToAction("Index", "Home2", data);
}
Notice that, this time the Customer object is passed as the third parameter of RedirectToAction() method. This way Customer data will be passed in the form of route parameter values. To receive this data the receiver action method should write something like this:
public ActionResult Index()
{
Customer data = new Customer();
UpdateModel(data);
return View(data);
}
// OR
public ActionResult Index(Customer data)
{
return View(data);
}
As shown above you can either use UpdateModel() method to transfer values from the route to the Customer object or you can have a parameter to the Index() action method.
This technique is quite clean and makes use of MVC specific parts (route and route parameters). It doesn't have any dependency on session state as in the case of TempData technique. On the other hand you need to create a route to deal with the route parameters.
Note about query string and route parameters
Before I conclude this post, it would be interesting to see a small thing about how RedirectToAction() deals with query string and route parameters.
Let's assume that your sender action is like this:
public ActionResult Index()
{
Customer data = new Customer()
{
CustomerID = 1,
CustomerName = "Abcd",
Country = "USA"
};
return RedirectToAction("Index", "Home2", data);
}
Notice that RedirectToAction() method passes Customer data object to Index() of Home2 as the third parameter.
The interesting thing to note is - If you haven't defined any route to match the data MVC sends it as query string. And if you have defined a route, it passes the values as route parameters. You can confirm this by observing the browser address bar once the Index() of Home2 renders the view. The following figure shows the difference:
That also means in the query string technique discussed earlier, you could have used exactly same code in the receiving action as in the case of route parameter technique.
In addition to the three techniques discussed above you can also use Session object but that's not discussed here separately since TempData technique anyway depends on the session storage.
That's it for now. Keep coding!