【问题标题】:ASP.NET MVC: Hidden field value does not get rendered using HtmlHelper.HiddenASP.NET MVC:隐藏字段值不会使用 HtmlHelper.Hidden 呈现
【发布时间】:2010-01-07 08:43:33
【问题描述】:

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

我的 ViewModel 中有以下属性:

public int? StakeholderId { get; set; }

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

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

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

我遇到的问题是隐藏字段在其“值”属性中没有任何内容,即使 StakeholderId 现在有一个值。

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

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

但是很奇怪,helper 没有获取更新后的值?

(我正在使用 jQuery 提交表单并将操作结果呈现到 div 中,但是我已经检查过,并且在 jQuery 对其进行任何操作之前,我返回的 html 已经是错误的,所以我认为没有太多做任何事)

更新

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

【问题讨论】:

    标签: c# .net asp.net-mvc html-helper


    【解决方案1】:

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

    【讨论】:

    • 谢谢,这很违反直觉,不是吗?如果我在 value 参数中传递一个具体的值,我肯定希望它被发出,否则我会完全忽略它?我想知道这种设计的原因是什么......
    • @veli - 原因是允许您放置“默认”或“初始值”,但如果它没有重新显示提交的值,那么您将丢失页面打开时发布的所有数据重新显示错误。更具体地说,它正在寻找 ModelState 值而不是 POSTed 值。如果您从 ModelState 中删除,则不会有此行为
    • 感谢达林,您能否发布一些有关该行为的官方文档的链接?谢谢
    • 当您需要将隐藏字段中的 POST 值替换为控制器中设置的模型值时,这是将其放入控制器的实际代码。 ModelState.Remove("StakeholderId");
    【解决方案2】:

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

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

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

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

    这按预期工作。

    即:

    当您在网格中使用多个表单时,永远不要使用 Html.Hidden 将参数传回您的操作!!!

    最后的警告:

    在构建隐藏的输入标签时,您需要同时包含名称和 ID,并设置为相同的值,否则,在撰写本文时(2011 年 2 月)它将无法正常工作。当然不是在谷歌浏览器中。如果你只有一个 id 没有 name 属性,你得到的只是一个返回的 null 参数。

    【讨论】:

    • 请注意一件事,提交表单数据时,name 属性用于向服务器标识数据,而不是 id。
    猜你喜欢
    • 2015-05-05
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多