【问题标题】:ASP.NET MVC auto-binds a refreshed model when ModelState is invalid on HttpPost当 ModelState 在 HttpPost 上无效时,ASP.NET MVC 自动绑定刷新的模型
【发布时间】:2010-11-02 07:26:36
【问题描述】:

我正在开发一个 ASP.NET MVC2 应用程序。我开始意识到 MVC 在幕后所做的与 ModelState 和模型绑定有关的一件非常令人惊讶但又令人惊奇的事情。我有一个 ViewModel,它有一大堆数据——一些字段是表单的一部分,而其他字段只是 UI 的一部分。在 HttpPost 上,我的 Action 方法使用 DefaultModelBinder 尝试绑定整个模型,但只有作为表单一部分的字段被成功反序列化 - 所有其他字段都保持为空。这很好,可以理解。如果 ModelState 无效,我需要从数据库中刷新模型并绑定那些特定的表单字段,然后返回到相同的编辑视图以显示那些关联的 ModelState 验证错误。

这就是我惊奇和好奇的地方。我的假设是,为了让我绑定表单字段与刷新的模型,我需要调用UpdateModel()TryUpdateModel<>(),传入新刷新的模型。例如:

[HttpPost]
public ActionResult EditDetail(EditDetailItemModel model)
{
    if (model.IsValid)
    {
        // Save the results to the db

        return RedirectToAction(...)
    }

    // Can't simply "return View(model)". Not all fields in EditDetailItemModel
    // were part of the form - thus they returned null. Have to refresh
    // model from the db.

    var refreshedModel = RefreshModelFromDB();

    // Is this line necessary?????
    TryUpdateModel<EditDetailItemModel>(refreshedModel);

    return View(refreshedModel);
}

但是,我发现如果我只是将refreshedModel 返回到视图而不调用TryUpdateModel&lt;&gt;()刷新的模型会自动与发布的表单字段值绑定!因此,这里不需要TryUpdateModel&lt;&gt;()

我能理解的唯一方法是,由于 ModelState 处于无效状态,一旦我返回带有刷新模型的视图,“MVC 渲染引擎”就会遍历 ModelState 错误并绑定这些属性值用我刷新的模型。这简直太棒了!但是,我想要证明这个假设。我在网络上的任何地方都找不到有关此的文档。任何人都可以确认我的假设为什么/如何发生这种令人敬畏的自动绑定行为和/或教育我为什么/如何发生,希望有一些在线文档链接支持,以便我更全面地了解幕后发生的事情?

【问题讨论】:

    标签: asp.net-mvc modelbinders updatemodel modelstate defaultmodelbinder


    【解决方案1】:
    public ActionResult EditDetail(EditDetailItemModel model)
    

    该行将执行模型绑定。将 ActionMethod 参数视为始终通过调用 UpdateModel 来填充。

    您在视图中看不到 refreshedModel 的值,您看到的是来自 EditDetailItemModel 的 ModelState 条目和值。

    【讨论】:

    • 对 - 我“回发”后在视图中看到的值是 ModelState 条目。但有一点不同——“其他”非形式属性不为空!如果我在发回视图之前没有刷新模型,那么其他属性仍然为空。但是因为我刷新了模型,所以当我在视图中设置断点时,我可以看到,不仅非表单属性正确恢复,而且表单属性也恢复为用户在表单中输入的值 - 完全正确我想要发生的事情。我正在寻找的是一些确认该功能的文档。
    • 没有任何在线(我能找到)谈到在返回显示验证错误之前必须“刷新”模型,我认为这很奇怪。这似乎是一件非常标准的事情,但我没有找到尝试这样做的例子。查看上面我的问题中的代码,如果我没有调用 TryUpdateModel(),那么“refreshModel”(其值直接来自数据库)将是显示给用户的值 -不是他们在发布之前输入的值。太棒了。如果我能在线阅读这个预期的功能,我的良心就会安定下来。
    • @tbehunin,我不明白你在找什么。当您调用return View(refreshedModel); 时,您正在将该视图模型传递给视图。事情就是这样运作的。 TryUpdateModel 将为该 refreshedModel 创建 ModelState 条目,任何 htmlhelper 都会在查看模型之前首先使用这些条目。
    猜你喜欢
    • 2012-03-09
    • 2017-02-13
    • 1970-01-01
    • 2019-08-23
    • 2017-05-30
    • 1970-01-01
    • 2015-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多