3

我有这个 POST 动作:

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

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

当我发布我的表单并执行此操作时,结果视图中没有任何更改。我的意思是,TextBoxforIdentifier没有我在操作中设置的“测试”字符串值。但如果我 clear ModelState,视图将显示新值:

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

我不明白为什么会这样?如果模型状态无效,为什么每个人都将模型返回给视图?例如,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);
}
4

1 回答 1

8

首先回答您的第二个问题:如果您不将模型对象传递给View(). 视图的Model属性将是null。在您看来,这意味着像这样简单的事情:

@Model.Identifier

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

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

在没有模型的情况下从您的 POST 方法调用时,例如HtmlHelper创建的输入字段和验证仍然View()有效的原因是:如果他们可以摆脱它,则辅助方法根本不使用模型的属性。他们将尝试按<input>以下顺序查找 eg s 的值:

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

第一个不为空的获胜。

换句话说,助手只会查看模型的Identifier属性是否ModelState["Identifier"]为空(或它Value为空)。

这也意味着像在第一个示例中所做的那样更改模型上的属性不会更改渲染字段的内容。如果用户输入“no, please don't test”,即使你发回带有“test”的模型,输入字段中的文本仍然是“no, please don't test”。

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

于 2013-07-16T17:26:27.517 回答