在POST操作中更改ViewModel属性

Wac*_*urn 3 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 
       });
}
Run Code Online (Sandbox Code Playgroud)

当我发布表单时,执行此操作后,生成的视图中没有任何更改.我的意思是,TextBoxfor Identifier没有我在动作中设置的"test"字符串值.但如果我清除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 
       });
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么会这样?如果模型状态无效,为什么每个人都将模型返回到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);
}
Run Code Online (Sandbox Code Playgroud)

Jim*_*iTh 8

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

@Model.Identifier
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

第一个不为null的人获胜.

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

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

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