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


71

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

我的ViewModel具有以下属性:

public int? StakeholderId { get; set; }

它以部分视图的形式呈现,如下所示:

<%= Html.Hidden("StakeholderId", Model.StakeholderId) %>

表单被提交,相关的控制器动作生成一个id并更新模型,然后返回与更新后的模型相同的视图

我遇到的问题是,即使StakeholderId现在具有值,隐藏字段在第二次呈现的“ value”属性中也没有任何内容。

如果我只是自己输出值,它将显示在页面上,因此我可以通过执行以下操作来呈现值:

<input type="hidden" id="StakeholderId" name="stakeholderId" value="<%: Model.StakeholderId %>" />

但是,助手没有获取更新的值,这很奇怪?

(我使用jQuery提交表单并将操作结果呈现到div中,但是我已经检查过,在jQuery执行任何操作之前,返回的html已经是错误的,因此我认为这与它没有太大关系任何东西)

更新

从那以后,我发现我也可以在控制器操作返回部分视图之前清除相关的ModelState键。

Answers:


61

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


8
谢谢,这很违反直觉,不是吗?如果我在value参数中传递一个具体值,那么肯定希望它被发出,否则我将完全忽略它吗?我不知道这种设计的原因是...
Veli Gebrev

3
@veli-原因是允许您放置“默认值”或“初始值”,但是如果它没有重新显示提交的值,那么当页面重新显示时会丢失所有带有错误的数据。更具体地说,它在寻找ModelState值而不是POSTED值。如果您从ModelState中删除,则不会出现这种情况
Simon_Weaver

谢谢达林,能否请您发布有关该行为的一些官方文档的链接?谢谢
pomarc 16'Dec

这是在需要将隐藏字段中的POSTed值替换为控制器中设置的模型值时将其放入控制器中的实际代码。ModelState.Remove(“ StakeholderId”);
泰伦斯·哥拉

34

附录:多个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>
        }

这里的致命线是:

@Html.Hidden("TutorName", username)

...,并打算将TutorName用作操作的参数。例如:

public virtual ActionResult DeleteTutor(string TutorName){...}

如果这样做,令人讨厌的是,正如Darin Dimitrov解释的那样,Html.Hidden(“ TutorName”,username)将呈现最后一个POSTed值。即,无论您是否循环,所有项目都将使用最后删除的Tutor的TutorName呈现!

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

<input type="hidden" id="TutorName" name="TutorName" value='@username' />

这按预期工作。

即:

当您在网格中使用多个表格时,永远不要使用Html.Hide隐藏参数来返回您的操作!!!

最终警告:

构造隐藏的输入标签时,您需要同时包含名称和ID,并设置为相同的值,否则,在撰写本文时(2011年2月),该标签将无法正常工作。当然不在Google Chrome中。如果您只有id且没有name属性,则返回的是一个空参数。


请注意,提交表单数据时,只有一件事,name属性是用来标识服务器数据的,而不是id。
欧文(Irwin)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.