Razor Html.HiddenFor和Html.Hidden未正确发回控制器

Razor Html.HiddenFor和Html.Hidden未正确发回控制器,razor,asp.net-mvc-5,html-helper,Razor,Asp.net Mvc 5,Html Helper,我在使用HiddenFor和Hidden Helper存储要发回控制器的数据时遇到问题。我有一个控制器,有两种方法: Function Index() As ActionResult Dim model As New FormPOSTViewModel With {.Name = "Test", .Description = "Test description goes here", .Value = 12} Return View(model) End Function &l

我在使用HiddenFor和Hidden Helper存储要发回控制器的数据时遇到问题。我有一个控制器,有两种方法:

Function Index() As ActionResult
    Dim model As New FormPOSTViewModel With {.Name = "Test", .Description = "Test description goes here", .Value = 12}
    Return View(model)
End Function

<HttpPost>
Function Update(model As FormPOSTViewModel) As ActionResult
    Dim updated As New FormPOSTViewModel
    updated.Name = model.Name & "_x"
    updated.Description = model.Description & "_x"
    updated.Value = model.Value * 2
    Return View("Index", updated)
End Function
我想做的是,每次按下Submit按钮时,模型都会被更新,并在末尾多次添加“x”,这样它就会以类似“Test_x_x_x_x_x_x”的方式结束。如果我在手动创建HTML的表单中使用Submit按钮,那么一切都正常

然而,当我启动这个按钮并按下其他提交按钮时,实际发生的情况是,只添加了一个“x”。这似乎是因为Update方法在第二次和后续时间接收的模型是由原始索引方法发送到页面的模型


这个bug是否隐藏了/HiddenFor,还是我使用它们不正确?

不,这不是bug。回发模型时,属性值将添加到
ModelState
。返回视图时,
ModelState
中的值优先于您可能尝试在控制器中重写的任何值。首先需要使用清除
ModelState

ModelState.Clear();
现在,当您设置属性值时,Html帮助程序将使用属性值。

其中包含问题说明以及为什么使用ModelState。需要清除调用:

ASP.NET MVC假定,如果您正在渲染视图以响应 HTTP POST,并且您正在使用Html帮助程序,那么您很可能 重新显示未通过验证的窗体。因此, Html帮助程序实际上在ModelState中签入要显示的值 在他们查看模型之前创建一个字段。这使它们能够重新显示 用户输入的错误数据,以及匹配错误 如有需要,请留言

因为我们的[HttpPost]索引重载依赖于与 解析POST数据时,ModelState已自动填充 字段的值。在我们的操作中,我们更改模型数据(而不是 ModelState),但Html帮助程序(即Html.Hidden和 (Html.TextBox)首先选中ModelState…并显示 是由行动接收的,而不是我们修改的

因此,要解决此问题,我们必须在控制器的更新方法中添加一行:

Function Update(model As FormPOSTViewModel) As ActionResult Dim updated As New FormPOSTViewModel updated.Name = model.Name & "_x" updated.Description = model.Description & "_x" updated.Value = model.Value * 2 ModelState.Clear() Return View("Index", updated) End Function 函数更新(模型为FormPOSTViewModel)为ActionResult Dim更新为新FormPOSTViewModel 更新的.Name=model.Name&“\u x” 更新的.Description=model.Description&“\u x” 更新的.Value=model.Value*2 ModelState.Clear() 返回视图(“索引”,已更新) 端函数
就个人而言,我认为我会将其归类为bug,即使MS认为它“按预期工作”,因为您显式传递给视图的对象不是视图实际使用的对象。太多的抽象。这不是一个bug。它以这种方式工作的原因在本文中得到了解释,充其量只是一个“特性”。很多人会将其定义为bug,因为为了使其按预期工作,您必须添加一个变通方法(ModelState.Clear)。设计缺陷在于,各种帮助器扩展依赖于读取用户未明确设置的数据。显式应该总是胜过隐式,但在这种情况下它不是——这是一个错误,而且是MVC框架过度依赖隐式的症状
ModelState.Clear();
Function Update(model As FormPOSTViewModel) As ActionResult Dim updated As New FormPOSTViewModel updated.Name = model.Name & "_x" updated.Description = model.Description & "_x" updated.Value = model.Value * 2 ModelState.Clear() Return View("Index", updated) End Function