在POST操作中更改ViewModel属性

时间:2013-07-16 15:38:17

标签: c# asp.net-mvc http-post

我有这个POST动作:

[HttpPost]
public ActionResult GetReport(GetReportModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    return View("GetReport", new GetReportModel()
       { 
          Identifier = "test", 
          Permission = true 
       });
}

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

ModelState

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

[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 
       });
}

1 个答案:

答案 0 :(得分:8)

首先回答您的第二个问题:如果您未将模型对象传递给View(),则该模型对象将不在那里。视图的Model属性为null。在您看来,这意味着一件简单的事情:

@Model.Identifier

...将以NullReferenceException失败。这是我们将模型传递回视图的原因之一。 ModelState无效并不重要(即使你没有传递模型,它也会被赋予视图) - 实际上,我们想要那个无效的状态,因为它是什么让我们能够为用户提供有用的错误消息。

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

原因如下HtmlHelper - 在没有POST方法的模型的情况下调用View()时,创建的输入字段和验证仍将工作:如果他们可以侥幸逃脱,那么辅助方法就不会根本不使用模型的属性。他们会试图找到例如<input>按此顺序:

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

第一个非空的胜利。

换句话说,如果Identifier为空(或者ModelState["Identifier"]为空),帮助程序只会查看模型的Value属性。

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

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