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

5
我想把一个类对象从一个控制器动作传递到另一个控制器的动作中。
发送者动作:
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);
}
}

我在发送方操作中正确获取数据,并且从重定向到操作调用中正确调用接收方操作。然而,在接收方操作courseVMnull

我知道这是一个非常古老的问题,已经反复询问过。但我发现大多数答案建议使用TempData并且是在2008/2009年回答的。我相信有一种方法可以使用RedirectToAction而不使用TempData传递数据。如果没有,那么我只能使用TempData。

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

类似的问题 问题1
问题2
问题3
问题4
问题5
问题6,尝试使用此问题但没有成功
问题7
问题8
问题9
问题10

上述问题中的大多数答案都可以追溯到2008/09年,并使用tempdata。

2个回答

4
这个问题本身已经有大约一年的历史了,但我看到它了,所以我想帮助未来遇到这个问题的其他人。被接受的答案不起作用——复杂对象仍然在接收操作中为空。我发现2012年的这个答案仍然有效。你只能传递标量值:int、string等,不能在HttpGet请求中传递复杂对象(这就是RedirectToAction的特性——你无法改变)。确保你已经排除了以下两个选项:
  • 完全避免发送复杂对象,只发送标量值。很明显,这只是一个有时的选择——但我提到它是为了提醒考虑它。
  • 完全跳过接收Get操作——从Post操作直接执行其逻辑并返回View。即:return View("ReceivingViewName", viewmodel)同样,只适用于某些情况,更有可能需要其他操作,因此需要重定向,但值得记住作为一种可能性。
如果你无法解决问题,并且已经排除了上述两个选项,那么你的选择是:
  • 将数据持久化到数据库中,如果你知道数据不会在后面使用,可以使用临时表。将主键发送到接收操作,然后在那里查询数据库。这是“最干净”的选择。
  • [编辑选项] 将对象存储在TempData(数据仅持续到下一个请求,在其中使用——如果没有使用,它将一直存在于会话的生命周期中)或Session(数据持续会话的生命周期)。两者都不是很好的选择。TempData可能是两者中较好的选择,因为它的寿命可能更短...但你仍然必须考虑当页面重新加载或对该方法进行后续请求时会发生什么情况(例如WebGrid分页——这就是我的场景)。对于这些特定的场景,我最初建议从TempData中取出数据,然后再将其放回,以便在后续请求该操作时可用。由于TempData实际上会一直保留到它被使用一次,所以这个选项甚至更不可取,因为如果用户导航到其他地方,它不会消失。关于这个问题的更多信息可以在这里的答案中找到。底线是除非你打算立即使用它,否则不要把任何东西放在TempData中。如果你不需要数据用于像分页这样的特定场景,并且你将其放入TempData并立即在接收方法中使用它,而不将其放回,则此选项是可以的。第一个选项仍然更好。

3

使用这个

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

在您的情况下
 return RedirectToAction("CreateNewProject", "Course", courseViewModel);

你可以使用以下方法:
 TempData

采用这种方法会有什么危害吗?即不使用TempData或ViewBag。 - Rohit
Rohit:我认为“RedirectToAction”是最好的方法。谢谢。 - Chandu
嘿,Pawanism,我在将课程 VM 从视图(.cshtml)发送到控制器时遇到了问题。它总是为空。 - Rohit
你是如何从视图或客户端调用动作的?这意味着你是通过Ajax调用还是在视图中使用BeginForm?检查所有参数是否传递正确。 - Chandu
我有一个带有填充模型的部分视图,因此所有值都从模型设置在一个页面上,现在我想在另一个页面上使用相同的部分视图,并且值也应该被填充在其他页面上,我该如何实现这一点? - Mayur Patel
1
这仅适用于传递基本数据类型,因为实际数据是通过查询字符串参数传递的。复杂对象在目标位置始终为空。 - spadelives

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接