5

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.

Community
  • 1
  • 1
Rohit
  • 6,365
  • 14
  • 59
  • 90

2 Answers2

4

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.
Community
  • 1
  • 1
EF0
  • 2,940
  • 4
  • 17
  • 23
3

use this

 return RedirectToAction("ActionName", "ControllerName", modelObj);

in your case

 return RedirectToAction("CreateNewProject", "Course", courseViewModel);

You can also use

 TempData
Vivek Ranjan
  • 1,432
  • 2
  • 15
  • 37
Chandu
  • 962
  • 2
  • 16
  • 33
  • Is there any harm in going with this approach? i.e. Not using TempData or ViewBag – Rohit Jul 12 '13 at 14:29
  • Rohit: I think "RedirectToAction" is the best approch to go. Thanks – Chandu Jul 12 '13 at 14:31
  • Hey Pawanism I'm having trouble in sending course VM from View (.cshtml) to controller. It is always coming as null – Rohit Jul 15 '13 at 14:48
  • how you are calling action from view or client side. Means its ajax call or using BeginForm in View. check all the arguments are passing properly. – Chandu Jul 16 '13 at 05:27
  • I have one partial view loaded with filled model so all values are set from model on one page now i want to use same partial view on other page and values should also be filled on other page how can i achieve this ? – Mayur Patel Mar 04 '16 at 04:55
  • 1
    This only works for passing primitive datatypes since the actual data is passed via querystring parameters. Complex objects are always null at the destination. – spadelives May 03 '17 at 15:50