为什么创建新的ViewModel会返回与旧ViewModel相同的数据?

时间:2012-06-13 16:24:40

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

我现在正在学习MVC3,这让我很困惑。

我有一个包含一些子ViewModel的ViewModel。每个ChildViewModel都使用不同的局部视图进行渲染,并在提交时对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吗?

2 个答案:

答案 0 :(得分:2)

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

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

原因是因为TextBoxFor等Html帮助程序在绑定它们的值时会首先查看模型状态,然后在模型中查找。由于modelstate已经包含POSTed值,所以使用的是=>该模型被忽略。这是设计的。

这就是说你要做的正确的事情就是简单地重定向到GET动作,该动作已经使模型空白并尊重Redirect-After-Post pattern

else
{
    return RedirectToAction("Index");
}

答案 1 :(得分:0)

  

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

因为字段的值是从POSTed表单而不是从模型中检索的。那有道理吗?我们不希望用户显示填写了与提交内容不同的值的表单。