在POST操作中更改ViewModel属性

我有这个POST动作:

[HttpPost] public ActionResult GetReport(GetReportModel model) { if (!ModelState.IsValid) { return View(model); } return View("GetReport", new GetReportModel() { Identifier = "test", Permission = true }); } 

当我发布表单时,执行此操作后,生成的视图中没有任何更改。 我的意思是, IdentifierTextBox没有我在动作中设置的“测试”字符串值。 但是如果我清除ModelState ,View将显示新值:

 [HttpPost] public ActionResult GetReport(GetReportModel model) { if (!ModelState.IsValid) { return View(); } ModelState.Remove("Identifier"); ModelState.Remove("Permission"); return View("GetReport", new GetReportModel() { Identifier = "test", Permission = true }); } 

我不明白为什么会这样? 如果模型状态无效,为什么每个人都将模型返回到View? 例如,Microsoft的默认项目模板具有以下代码:

 public ActionResult Login(LoginModel model, string returnUrl) { if (ModelState.IsValid) { return RedirectToLocal(returnUrl); } // Why do they pass the model object to the view // if it will be there anyway from post data? return View(model); } 

首先回答你的第二个问题:如果没有将模型对象传递给View() ,模型对象就不会存在。 视图的Model属性为null 。 在您的视图中,这意味着一些简单的事情:

 @Model.Identifier 

…将因NullReferenceException而失败。 这是我们将模型传递回视图的原因之一。 ModelState无效并不重要(即使你没有传递模型,它也会被赋予视图) – 实际上,我们想要这个无效状态,因为它允许我们给用户提供有用的错误消息。

但是你的第一个问题实际上有一个好处,很少有MVC程序员似乎意识到,因为它在最常见的用例中是透明的:

原因如下HtmlHelper创建的输入字段和validation仍然可以在没有POST方法的模型的情况下调用View()时:如果他们可以侥幸使用它,那么辅助方法根本不使用模型的属性。 他们将尝试按以下顺序查找例如的值:

  • ModelState["Identifier"].Value
  • ViewData (仅在某些情况下)
  • 模型的价值。

第一个非null获胜。

换句话说,如果ModelState["Identifier"]为null(或其Value为null),则帮助程序将仅查看模型的Identifier属性。

这也意味着像第一个示例中那样更改模型的属性不会更改渲染字段的内容。 如果用户输入“否,请不要测试”,即使您发送带有“测试”的模型,输入字段中的文本仍将是“否,请不要测试”。

所以是的,如果您需要为输入设置新值作为对POST的响应,则需要从ModelState删除它们的状态。 或者不使用HTML帮助程序。