ASP.NET MVC:使用HtmlHelper.Hidden不会呈现隐藏字段值

Vel*_*rev 71 .net c# asp.net-mvc html-helper

我的应用程序发生了一些非常奇怪的事情:

我的ViewModel中有以下属性:

public int? StakeholderId { get; set; }
Run Code Online (Sandbox Code Playgroud)

它在部分视图中呈现如下:

<%= Html.Hidden("StakeholderId", Model.StakeholderId) %>
Run Code Online (Sandbox Code Playgroud)

提交表单,相关控制器操作生成id并更新模型,然后返回具有更新模型的相同视图

我遇到的问题是隐藏字段第二次呈现的"值"属性中没有任何内容,即使StakeholderId现在有值.

如果我只是自己输出值,它会显示在页面上,所以我通过这样做来渲染值:

<input type="hidden" id="StakeholderId" name="stakeholderId" value="<%: Model.StakeholderId %>" />
Run Code Online (Sandbox Code Playgroud)

但是帮助者没有获得更新的值这很奇怪?

(我正在使用jQuery提交表单并将动作结果呈现为div,但是我已经检查过了,我回来的html已经错了,之后jQuery对它做了什么,所以我认为这与任何东西)

UPDATE

我发现在控制器操作返回局部视图之前,我还可以清除相关的ModelState键.

Dar*_*rov 61

帮助程序将首先查找POSTed值并使用它们.当您发布表单时,它将获取ID的旧值.您的解决方法是正确的.

  • 谢谢,这是非常反直觉的,不是吗?如果我在value参数中传递一个具体值,我肯定希望它被发出,否则我会完全省略它?我想知道这个设计的原因是什么...... (8认同)
  • @veli - 原因是允许您设置"默认"或"初始值",但如果它没有重新显示提交的值,那么当页面重新显示错误时,您将丢失所有已发布的数据.更具体地说,它正在寻找ModelState值而不是POSTed值.如果从ModelState中删除,则不会出现此行为 (3认同)

awr*_*ley 34

ADDENDUM:多个HTML表单,例如,在网格中

作为这个问题的一个重点,有一件事要非常小心,就是在同一页面上有多个表单,例如,在网格中,比如使用Ajax.BeginForm生成的表单.

您可能会想要写下以下内容:

@foreach (var username in Model.TutorUserNames)
        {
            <tr>
                <td>
                    @Html.ActionLink(username, MVC.Admin.TutorEditor.Details(username))
                </td>
                <td>
                    @using (Ajax.BeginForm("DeleteTutor", "Members",
                        new AjaxOptions
                        {
                            UpdateTargetId = "AdminBlock",
                            OnBegin = "isValidPleaseWait",
                            LoadingElementId = "PleaseWait"
                        },
                        new { name = "DeleteTutorForm", id = "DeleteTutorForm" }))
                    {    
                        <input type="submit" value="Delete" />
                        @Html.Hidden("TutorName", username)
                    }
                </td>
            </tr>
        }
Run Code Online (Sandbox Code Playgroud)

这里的致命线是:

@Html.Hidden("TutorName", username)
Run Code Online (Sandbox Code Playgroud)

...并打算使用TutorName作为动作的参数.例如:

public virtual ActionResult DeleteTutor(string TutorName){...}
Run Code Online (Sandbox Code Playgroud)

如果你这样做,那么令人讨厌的惊喜就是Html.Hidden("TutorName",用户名)将如Darin Dimitrov所解释的那样呈现最后一个POSTed值.即,无论您的循环如何,所有项目都将使用上次删除的导师的TutorName进行渲染!

Razor语法中的单词是用显式输入标记替换@ Html.Hidden调用:

<input type="hidden" id="TutorName" name="TutorName" value='@username' />
Run Code Online (Sandbox Code Playgroud)

这按预期工作.

即:

永远,永远使用Html.当您在网格中使用多种形式时,隐藏通过参数回到您的行动!

最后的警告:

构建隐藏的输入标记时,需要同时包含name和id,设置为相同的值,否则,在编写本文时(2011年2月),它将无法正常工作.当然不在Google Chrome中.如果您只有id而没有name属性,那么您只需返回一个null参数.