隐藏未从视图模型中获取正确的值

use*_*875 45 asp.net-mvc

我有一个多步骤文件导入过程.我在视图中有一个隐藏的表单输入,我试图用视图模型中的"CurrentStep"填充.

<% = Html.HiddenFor(model => model.CurrentStep) %>
Run Code Online (Sandbox Code Playgroud)

CurrentStep是一个枚举,我总是得到默认值,而不是我提供给视图模型的默认值.另一方面,这给了我正确的价值:

<p><% = Model.CurrentStep %></p>
Run Code Online (Sandbox Code Playgroud)

我意识到我可以手工编写隐藏的输入,但我想知道:我做错了什么?有没有更好的方法来跟踪POST之间的当前步骤?

Dar*_*rov 73

你做错了是你试图修改控制器动作中POSTed变量的值.所以我想你正在尝试这样做:

[HttpPost]
public ActionResult Foo(SomeModel model)
{
    model.CurrentStep = Steps.SomeNewValue;
    return View(model);
}
Run Code Online (Sandbox Code Playgroud)

和HiddenFor之类的html助手将始终首先使用POSTed值,然后使用模型中的值.

所以你有几种可能性:

  1. 从模型状态中删除值:

    [HttpPost]
    public ActionResult Foo(SomeModel model)
    {
        ModelState.Remove("CurrentStep");            
        model.CurrentStep = Steps.SomeNewValue;
        return View(model);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 手动生成隐藏字段

    <input type="hidden" name="NextStep" value="<%= Model.CurrentStep %>" />
    
    Run Code Online (Sandbox Code Playgroud)
  3. 编写一个自定义帮助程序,它将使用模型的值而不是正在POST的那个

  • @DarinDimitrov.当然这不是由MS来决定的.如果我更改发布值,我会故意这样做.为什么MVC需要覆盖我的偏好?这个功能有什么好处?如果我忽略了一些非常明显的事情,我会道歉! (10认同)
  • 谢谢,很好的答案.对于(1),您还可以使用ModelState.Clear()删除所有值. (4认同)
  • 谢谢.我认为视图模型的重点是将复杂(比ViewData中应该包含的更复杂)信息传递给View.所以View没有使用我传递给它的View Model?它只是获得POST变量中的任何内容?这对我来说没有多大意义. (2认同)
  • @Darin Dimitrov:我们遇到了类似的问题,你的帖子给了我们很多帮助.但是,我们没有得到,也许你有答案,是为什么它这样做.为什么它会从POST中获取值,即使您似乎使用.cshtml中模型的值覆盖它. (2认同)
  • 因为这是用户在99.99%的情况下想要的行为:他希望看到他在回发后在表单中输入的相同值,而不是您在POST操作中分配的一些新值.想象一下,用户在文本框中键入了一些值,然后发生了一些模型错误,您修改了该值并重新显示该表单.用户可能不会注意他输入的值被修改.这就是为什么这是默认行为的原因:因为在大多数情况下,您不应该修改用户将您发送到POST操作的内容. (2认同)

Zac*_*Zac 7

我的解决方案是使用Darin的第二个选项,因为选项1(从模型状态清除)意味着对字符串进行硬编码(并且复杂模型的命名约定可能很棘手),并且想要避免选项3,因为我已经有很多自定义助手.

<input type="hidden" name="@Html.NameFor(x => Model.SomeId)" value="@Model.SomeId" />

只是提醒您可以使用Html.NameFor以保持清洁.