Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a class object from one controller action to different controller action in ASP.net MVC 4

I want to pass a class object from one controller action to different controller's action.

Sender Action

public class CourseController : Controller
{
[HttpPost]
public ActionResult CreateNewCourse(CourseViewModelBase courseViewModel)
{
   if (ModelState.IsValid)
   {
       // Do some stuff
       return RedirectToAction("CreateNewProject", "Project",
                          new { courseVM = courseViewModel});
   }
   // Bad happened    
   return View("CreateNewCourse", courseViewModel);
}

Receiver Action

public class ProjectController : Controller
{
[HttpGet]
public ActionResult CreateNewProject(CourseViewModelBase courseVM)
{
      // Use CourseVM data and do other stuff
     return View("Create", projectCreateViewModel);
}
}

I am getting data properly in Sender Action and Receiver Action is called properly from the redirect to action call. However courseVM in Receiver Action is null.

I know this is a very old question and had been asked repetitively. But I found that most of the answers suggested to use TempData and were answered in 2008/2009. I believe there would be someway to pass data using RedirectToAction without using TempData. If there is not then I would go with TempData only.

Finding If I pass some simple data e.g. new {id = courseViewModel.CourseDuration} and change the argument in Receiver action to id then id is properly received.

Similar Questions Question 1
Question 2
Question 3
Question 4
Question 5
Question 6, tried to use this one but did not workout
Question 7
Question 8
Question 9
Question 10

Most of the answers in above questions are dated back in 2008/09 and uses tempdata.

like image 911
Rohit Avatar asked Mar 24 '23 04:03

Rohit


1 Answers

This question itself is now about a year old, but I came across it so I thought I would help out others who come across it in the future. The accepted answer doesn't work - the complex object still arrives at the receiving action null.

I found that this answer from 2012 is still valid. You just can't pass complex objects in an HttpGet request (by nature this is what a RedirectToAction is - again, not something you can change). You can only pass scalar values: int, string, etc.

Make sure you've ruled out the below two options:

  • Avoid sending a complex object altogether, and send only scalar values. Obviously this is only an option sometimes - but I mention it as a reminder to consider it.
  • Skip the receiving Get action altogether - perform its logic & return the View directly from your Post action. Ie; return View("ReceivingViewName", viewmodel) Again, will only work for some situations, more than likely you'll need the other action and thus will need the Redirect, but worth remembering as a possiblity.

If you can't get around the problem, and have eliminated the two above options, your options are:

  • Persist the data to Database, possibly using a temp table if you know the data won't be used later. Send the primary key to the receiving action, and once there, query the database. This is the "cleanest" option.
  • [Edited Option] Store the object in TempData (data lasts only thru the next request in which it is used - if it's not used, it will hang around for the life of session) or Session (data lasts for life of session). Neither are really great options. TempData is probably the better of the two, as its lifespan is potentially shorter... but you'll still have to consider what happens when a page reload occurs or a subsequent request is made to the method (WebGrid paging, for example - which was my scenario). For these specific scenarios, I originally recommended getting the data out of TempData, and then putting it back in so it's available for a subsequent request to that action. Since TempData actually hangs around until it's used once, that makes this option even less desirable, since it won't go away if the user navigates elsewhere. More info on this in the answers here. Bottom line is don't put anything in TempData unless you intend to use it right away. If you don't need the data for a specific scenario like paging, and you put it in TempData and immediately consume it in the receiving method, without putting it back in, this option is okay. The first option is still better.
like image 140
EF0 Avatar answered Apr 06 '23 06:04

EF0