将一个类对象从一个控制器操作传递到ASP.net MVC 4中的不同控制器操作

时间:2013-07-12 14:09:45

标签: asp.net-mvc asp.net-mvc-4 controller 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);
}

接收者行动

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

我正在发件人操作中正确获取数据,并且从重定向到操作调用正确调用 Receiver Action 。但 Receiver Action 中的 courseVM null

我知道这是一个非常古老的问题,并且一再被问到。但我发现大多数答案建议使用TempData并在2008/2009年得到回答。我相信使用RedirectToAction without using TempData传递数据会有所改变。如果没有,那么我只会使用TempData。

查找 如果我传递一些简单数据,例如new {id = courseViewModel.CourseDuration}并将Receiver操作中的参数更改为id,然后正确接收id。

类似问题 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

上述问题中的大部分答案都可追溯到2008/09年,并使用了tempdata

2 个答案:

答案 0 :(得分:4)

这个问题本身现在已经有一年了,但我遇到了它,所以我想我会帮助将来遇到它的其他人。接受的答案不起作用 - 复杂对象仍然到达接收操作null。

我发现2012年的this answer仍然有效。您只是无法在HttpGet请求中传递复杂对象(本质上这就是RedirectToAction - 再次,不是您可以更改的内容)。您只能传递标量值:int,string等。

确保您排除了以下两个选项:

  • 避免完全发送复杂对象,并仅发送标量值。显然这有时只是一种选择 - 但我提醒它考虑它。
  • 完全跳过接收Get动作 - 执行其逻辑&直接从Post操作返回View。即; return View("ReceivingViewName", viewmodel)同样,只会在某些情况下起作用,更可能是您需要其他操作,因此需要重定向,但值得记住可能性。

如果您无法解决问题,并且已经取消了上述两个选项,那么您的选择是:

  • 如果您知道以后不会使用的数据,可能会使用临时表将数据保留到数据库。将主键发送到接收操作,然后在那里查询数据库。这是最干净的"选项。
  • [已编辑选项]将对象存储在TempData中(数据仅持续到下一个使用它的 - 如果未使用,它将在生命周期中保持不变会话)或会话(数据持续一段时间)。两者都不是很好的选择。 TempData可能是两者中较好的,因为它的生命周期可能更短......但是你仍然需要考虑当页面重新加载发生时或者对方法发出后续请求时会发生什么(例如WebGrid分页 - 这是我的情景)。对于这些特定情况,我最初建议从TempData中获取数据,然后将其重新放入,以便后续请求执行该操作。由于TempData实际上一直挂起,直到它 一次使用,这使得这个选项更不可取,因为如果用户导航到别处,它就不会消失。有关详细信息,请参阅答案here。除非您打算立即使用,否则底线不会在TempData中放置任何内容。如果你不需要像分页这样的特定场景的数据,你把它放在TempData中并立即在接收方法中使用它,而不将其重新放入,这个选项是可以的。第一种选择仍然更好。

答案 1 :(得分:3)

使用此

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

在你的情况下

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

您也可以使用

 TempData