HTML.HiddenFor值设置

62
@Html.HiddenFor(model => model.title, new { id= "natureOfVisitField", @value = '@Model.title'})

它不起作用!如何设置值?

7个回答

113

要在隐藏字段中设置值,可以按照以下方式操作:

@Html.HiddenFor(model => model.title, 
                new { id= "natureOfVisitField", Value = @Model.title})

它会工作


我知道我比这晚了2年以上,但需要注意的是,用这个标记呈现的HTML标签将具有不同的“Value”和“value”标记。您应该使用“value”,因为控制器将在那里寻找您的数据。 - Ortund
3
不,@Ortund,错了!相反,应该从“CAP”开始。 - Alexander

60

奇怪但是,请尝试使用@Value,大写字母"V"

例如(适用于MVC4)

@Html.HiddenFor(m => m.Id, new { @Value = Model.Id })

更新:

发现@Value(大写V)会创建另一个带有“Value”属性的“value”,使用小写的@value似乎也可以正常工作!

需要检查MVC源代码以获取更多信息。


更新,在深入了解其内部工作方式后:

首先,请忘记所有这些解决方法(我为了连续性而保留的),现在看起来很傻 :)

基本上,当模型被发布并将模型返回到同一页面时,就会发生这种情况。

使用以下代码片段在InputHelper方法(InputExtensions.cs)中访问值(并形成html):

string attemptedValue = (string)htmlHelper.GetModelStateValue(fullName, typeof(string));

GetModelStateValue方法(位于Htmlelper.cs中)以原样检索值。

ViewData.ModelState.TryGetValue(key, out modelState)
这里的问题在于,由于从 ViewData.ModelState 字典中访问了值,所以返回的是页面提交的值,而不是修改后的值!
也就是说,如果您变量的提交值(例如Person.Id)为0,但在httpPost操作中设置该值(例如Person.Id = 2),则ModelState仍保留旧值“0”,attemptedValue包含“0”!因此,在呈现的页面中,该字段将包含“0”作为值!!
解决方法:如果要将模型返回到同一页,则清除ModelState中的项,
例如:
ModelState.Remove("Id"); 

这将从字典中删除该项,ViewData.ModelState.TryGetValue(key, out modelState)返回 null,接下来的语句(在 InputExtensions.cs 内部)获取传递给 HiddenFor(m => m.Id) 的实际值 (valueParameter)。

这是在 InputExtensions.cs 中以下行中完成的。

tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(fullName, format) : valueParameter), isExplicitValue);

摘要:

使用以下代码清除ModelState中的项目:

ModelState.Remove("...");

希望这对你有所帮助。


2
我觉得这很奇怪,但似乎是正确的。我在控制器中添加了ModelState.Remove("<columnName>"),我的问题就解决了。 - RitchieD
1
太棒了。这个问题花费了一些时间,以及找到这个答案。这让我担心可能我在其他地方也错过了类似的细节。 - David L Morris
2
"V"这个值对我有用,实际上非常奇怪!非常感谢。 - AaBa
4
更新应该添加到被接受的答案中-这个见解是无价的!非常感谢Tejasvi Hedge分享它。 - Alexander Mihailov
1
难以置信。谢谢Tejasvi!在我的情况下,我添加的代码看起来像这样(这可能会帮助某些人)ModelState.Remove("Invoice.InvoiceId"); - shlgug
显示剩余3条评论

29

您不需要在属性参数中设置值。MVC 应该会自动为您绑定。

@Html.HiddenFor(model => model.title, new { id= "natureOfVisitField" })

1
没关系,但我犯了一个大错误!抱歉!谢谢。 - arnoldrob
@EdPlunkett 为什么不行呢?除非你在控制器的get方法中设置了值并将其发送到视图,否则它会完美地工作。 - Cybercop
@Biplov13 说真的,它没有起作用。我现在认为它没有工作的原因是我的操作方法没有接受模型作为参数,或者可能它没有被标记为[HttpGet],或类似的东西。不幸的是,我现在没有时间回去重新创建它并找出问题所在。 - 15ee8f99-57ff-4f92-890c-b56153
1
请查看下面@Tejasvi Hegde的答案以获得更全面的理解。 - David L Morris
这对我有效。使用.NET 4.5.2和ASP.NET MVC 4。 - levininja
1
感谢@Cybercop - 如果您在控制器的get方法中发送了相同的模型,那么对我来说问题就解决了。使用hiddenFor设置值无效,因为get方法的值仍然存在(在我的情况下为null)。 - Chris

12

仅仅是值,不是 @value。
试试看。我不确定 @Model.title,可能只是 Model.title。


@arnoldrob 你两个都试过了吗?应该是这样的:@Html.HiddenFor(model => model.title, new { id= "natureOfVisitField", Value = '@Model.title'}) 或者只有 Model.title 在最后面。在我的项目中可以运行。 - der_chirurg
仍适用于 MVC 5。注意:Value 区分大小写。 - RoLYroLLs

4

我最近遇到了一个问题,想要给一个已有的实体添加一个相关属性。为了解决这个问题,我写了一个好用的扩展方法:

    public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, TProperty value)
    {
        string expressionText = ExpressionHelper.GetExpressionText(expression);
        string propertyName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expressionText);

        return htmlHelper.Hidden(propertyName, value);
    }

使用方法如下:
@Html.HiddenFor(m => m.RELATED_ID, Related.Id)

需要注意的是,这个方法和内置的 HiddenFor 签名类似,但使用了泛型类型。所以,如果 Value 是 System.Object 类型,你实际上会调用框架内置的 HiddenFor 方法。不过我不确定为什么你会在视图中编辑 System.Object 类型的属性...


0

在指定HtmlAttributes时,@符号用于"thing"是c#关键字的情况。例如,单词class,您不能指定class,必须使用@class。


-1

你可以这样做

@Html.HiddenFor(model=>model.title, new {ng_init = string.Format("model.title='{0}'", Model.title) })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接