当有多个同名输入时,MVC 如何决定绑定哪个值?

How does MVC decide which value to bind when there are multiple inputs with the same name?

我有一个编辑页面,根据用户的角色,有条件地禁用了几个字段。当字段被禁用时,它们的值不会发布到服务器(如预期的那样),这会导致 ModelState 无效,因为值是必需的。

为了解决这个问题,我想为字段添加 Html.HiddenFor();这样仍然会发布一个值(并且如果返回视图,它将保留这些值)。但是,在这些字段未被禁用的情况下,我会将 TextBoxFor 和 HiddenFor 都转到同一模型 属性.

我有 运行 几个测试,似乎发生这种情况时,表单上第一个元素的值将绑定到模型,而下一个元素将被忽略。如果是这种情况,那么我应该可以将 HiddenFor 放在 TextBoxFor 之后,在这种情况下,只有在禁用常规输入时才会发布隐藏输入的值。

@Html.TextBoxFor(m => m.FirstName)
@Html.HiddenFor(m => m.FirstName) @*Only gets binded to the model if the above text box is disabled*@

(有一些 JavaScript 有条件地禁用了可见的文本框)。

所以有两个问题:1) 是否记录了 MVC 绑定将始终以这种方式工作;我可以安全地拥有这两个字段吗?

并且,2) 是否有更好的方法来完成此任务?我知道我可以将 HiddenFor 放在 @If 语句中,这样只有在禁用 TextBox 时才会创建它;但这是我想避免的视图中的许多额外逻辑。

DefaultModelBinder 按顺序从请求中读取值并绑定第一个匹配的 name/value 对并忽略后续匹配(除非 属性 是 IEnumerable)。这就是 CheckBoxFor() 方法如何确保始终将 truefalse 值提交给控制器(该方法生成一个带有 value="True" 的复选框和一个带有 [=16] 的隐藏输入=]), 所以你可以安全地在文本框后面添加隐藏的输入。

您可能会考虑将其设为 readonly,而不是禁用文本框如果这是你想要的,请禁用)。