1

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

我有一个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显示的新副本?ParentViewParentViewModel

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

4

2 回答 2

2

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

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

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

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

else
{
    return RedirectToAction("Index");
}
于 2012-06-13T16:51:17.713 回答
0

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

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

于 2012-06-13T16:43:15.817 回答