【问题标题】:Switching MVC view on Post back using strongly typed views/view models使用强类型视图/视图模型在 Post back 上切换 MVC 视图
【发布时间】:2014-10-28 20:05:03
【问题描述】:

Step1 的用户请求页面,填写并提交包含所选人员的表单,到目前为止一切顺利。在验证 ModelState 之后,下一个视图模型将使用所选人员正确构建。然后,我尝试使用 newVM 重定向到操作,但在进入 Step2 时发现 MVC 清除了试图传入的视图模型。我怀疑这是由于 MVC 如何根据查询字符串结果尝试新建和实例。我会在其中设置一个断点并检查它,但我想知道如何使用传入的新视图模型从帖子中更改视图?

public ActionResult Step1()
{
    var vm = new VMStep1();
    return View(vm);
}

[HttpPost]
public ActionResult Step1(VMStep1 vm)
{
    if (ModelState.IsValid)
    {
        var newVM = new VMStep2(vm.SelectedPerson);
        return RedirectToAction("Step2", newVM);
    }
    return View(vm);
}

public ActionResult Step2(VMStep2 vm)
{
    return View(vm);
}

我可以通过在 Step1 视图中包含 VMStep2 和 Step2 的部分内容来解决此问题,但是当我真的只想让用户看到 Step2 时,这需要隐藏和查找逻辑。

【问题讨论】:

  • 您需要将newVM 分配给会话(或将某些内容保存到数据库),然后在Step2 方法中检索它(也可以使用TempData,但如果用户刷新它会失败浏览器)
  • 感谢 Stephen,这正是我所害怕的,但是我们必须遵守 MVC 规则。
  • 不确定您所说的必须遵循 MVC 规则是什么意思?创建多步骤向导的两种方法是 1. 带有部分的单个表单,其中每个部分包含验证每个部分的下一个/后退按钮,然后使下一个部分可见并隐藏当前部分,最后一个部分包含提交按钮,或 2.as shown in this answer
  • MVC 规则是这样的:如果您使用强类型视图和接受这些类型作为参数的控制器,则默认情况下 MVC 会接管。它基于强类型视图强制输入和操作结果。目前没有办法使用一种视图模型进入控制器并返回另一种视图模型类型的结果。所以我为克服这个问题所做的就是在第一个视图模型中包含第二个视图模型,并简单地调用基于“其他”视图模型的局部视图。
  • 这不是“规则”!如果VMStep2 仅包含原始属性,那么您的代码可以正常工作(RouteValueDictionary 是根据您的模型的属性生成的)。

标签: asp.net-mvc-4 viewmodel asp.net-mvc-viewmodel


【解决方案1】:

我不明白你为什么要打电话给RedirectToAction!它的作用如下: 它告诉您的浏览器重定向和喜欢它与否您的浏览器不理解如何处理您的对象——它理解的是 JSON。因此,如果您真的坚持使用return RedirectToAction("Step2", newVM);,您应该考虑一种将您的VMStep2 对象序列化为JSON 的方法,当浏览器请求重定向时,它将在您的操作方法public ActionResult Step2(VMStep2 vm) 中正确传递和创建

但是我会使用更简单的方法 --- 而不是

return RedirectToAction("Step2", newVM);

我会用

return View("Step2", newVM);

【讨论】:

  • 好吧,我想你证实了我的发现,当进入 Step2 时,数据丢失了,因为 MVC 模型绑定器使用请求数据(类似于 JSON)为 Step2 构建 ViewModel。数据丢失,因为 VMStep2 从来没有任何特定的入站请求数据。
【解决方案2】:

感谢大家的大力投入!

这就是我所做的......

  1. 我创建了三个视图 MainView、Step1View、Step2View(第 1 步和第 2 步是部分强类型视图)
  2. 我创建了一个包含 VMStep1 和 VMStep2 的 MainViewModel
  3. 当控制器为 Step1 提供服务时,MainViewModel 仅初始化 VMStep1 并设置状态逻辑来告诉 MainView Step1 将被显示。
  4. 当用户发回包含 MainViewModel 的 MainView 时,MainViewModel 通过 VMStep1 中提供的答案知道要做什么。
  5. VMStep2 在回传时初始化,状态设置为告诉 MainView 显示 Step2。 VMStep1 不再相关并设置为空。
  6. 用户现在可以使用 VMStep2 进行回答,一切正常。

这个工作的关键是一些标志告诉视图显示哪个部分,部分采用支持它的强类型的模型,该模型在正确的时间初始化。最终结果是快速渲染和良好的状态机进程。

【讨论】:

    猜你喜欢
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多