【问题标题】:Why does creating a new ViewModel return the same data as the old ViewModel?为什么创建新 ViewModel 会返回与旧 ViewModel 相同的数据?
【发布时间】:2012-06-13 16:24:40
【问题描述】:

我现在刚刚学习 MVC3,这真的让我很困惑。

我有一个包含一些子 ViewModel 的 ViewModel。每个 ChildViewModel 都使用不同的 Partial View 渲染,并在提交时在 Controller 上执行不同的操作。所有 ChildViewModel 都应该对其数据执行一些自定义验证,如果成功,它应该转到下一页。如果验证失败,它应该简单地返回到ParentView 并显示错误。

[HandleError]
public class MyController: Controller
{
    public ActionResult Index()
    {
        var viewModel = new ParentViewModel();
        return View("ParentView", viewModel);
    }

    [HttpPost]
    public ActionResult ChildViewModelB_Action(ChildViewModelB viewModel)
    {
        if (ModelState.IsValid)
        {
            return View("ChildViewModelB_Page2", viewModel);
        }
        else
        {

            // I'm having trouble returning to the ParentView and
            // simply displaying the ChildViewModel's errors, however
            // discovered that creating a new copy of the VM and displaying 
            // the ParentView again shows the existing data and any errors
            // But why??
            var vm = new ParentViewModel();
            return View("ParentView", vm);
        }
    }
}

例如,

  • 页面加载有 3 个选项。
  • 用户选择选项 B 并填写表格。
  • 提交后,子 ViewModel B 得到验证并失败。
  • 页面返回 ParentView,ChildB 全部填写完毕,但 ChildB 错误现在也显示出来了。

为什么创建ParentViewModel 的新副本会显示ParentView 与原始ParentViewModel 具有相同的数据?

在进行服务器端验证后,我应该以不同的方式返回 ParentView 吗?

【问题讨论】:

  • 如果验证失败,为什么不想在父视图中显示错误?
  • @Mark 我确实想...我只是不知道怎么做。我发现在ParentView 中显示错误的唯一方法是创建一个新的 ParentViewModel 并返回视图,但是对于我来说这没有任何意义
  • 我想我现在明白了这个问题..会更新答案。
  • ChildViewModelB_Page2 是局部视图吗?
  • @Mark 是的,它是部分视图

标签: asp.net-mvc asp.net-mvc-3 model-view-controller


【解决方案1】:

如果您打算修改 POST 操作中的值,则需要清除模型状态

else
{
    ModelState.Clear();
    var vm = new ParentViewModel();
    return View("ParentView", vm);
}

这是因为诸如 TextBoxFor 之类的 Html 助手在绑定它们的值时会首先查看模型状态,然后再查看模型。而且由于模型状态已经包含 POSTed 值,这就是所使用的 => 模型被忽略。这是设计使然。

这就是说,在您的情况下正确的做法是简单地重定向到已经使模型空白的 GET 操作并尊重Redirect-After-Post pattern

else
{
    return RedirectToAction("Index");
}

【讨论】:

  • 谢谢,现在一切都变得更有意义了! :)
  • @Rachel 你告诉过你想在 ParentView 中显示错误。但我认为这不会显示错误
  • @Mark 我可能误解了你的问题。错误出现在 PartialView 中,它是 ParentView 的一部分。
【解决方案2】:

为什么创建 ParentViewModel 的新副本会显示 ParentView 与原始 ParentViewModel 数据相同?

因为字段的值是从 POST 表单中检索的,而不是从模型中检索的。这是有道理的吧?我们不希望用户显示一个填充了与他们提交的值不同的值的表单。

【讨论】:

    猜你喜欢
    • 2021-05-29
    • 2017-05-05
    • 2020-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多