Html.Hidden和Html.HiddenFor有什么区别?

76
我可以在 MSDN 上找到 Html.HiddenFor 的良好定义,但是我只能在 Html.Hidden 相关的问题上找到一些信息。
请问有人能够给我一个良好的定义和示例吗?

参考:https://learn.microsoft.com/en-us/dotnet/api/system.web.mvc.html.inputextensions.hiddenfor?view=aspnet-mvc-5.2 - carloswm85
6个回答

136

大多数MVC帮助程序方法都有一个XXXFor变体。它们旨在与具体的模型类一起使用。这个想法是允许帮助程序基于您在lambda中指定的属性推导出表单输入控件的适当"name"属性。这意味着您可以消除您否则必须使用来将模型属性与视图相关联的"魔术字符串"。例如:

Html.Hidden("Name", "Value")

将导致:

<input id="Name" name="Name" type="hidden" value="Value">
在你的控制器中,你可能有一个像这样的操作:

[HttpPost]
public ActionResult MyAction(MyModel model) 
{
}

同时,一个像这样的模型:

public class MyModel 
{
    public string Name { get; set; }
}

我们之前使用的原始Html.Hidden将与模型中的Name属性关联。但是,有点不好的是,必须使用字符串("Name")指定属性的值"Name"。如果您重命名模型中的Name属性,您的代码将出现错误,而且这种错误有些难以排查。另一方面,如果您使用HiddenFor,则可以免受此类问题的影响:

Html.HiddenFor(x => x.Name, "Value");

现在,如果您重命名Name属性,则会收到一个明确的运行时错误,指示找不到该属性。此外,您还可以获得静态分析的其他好处,例如在键入x.后获得成员下拉列表。


2
谢谢Kirk,关于控制器和模型中发生的事情的信息很有用。 - Joe Pitz
5
如果你重命名属性,实际上你会得到一个编译器错误而不是运行时错误。这就是要点所在,出错是在编译时而不是运行时。 - Erik Funkenbusch
2
@Mystere Man,视图通常不会在构建解决方案时编译。这是一个手动步骤,需要使用VS来为您编译它们。 - Kirk Woll
2
实际上,这是一个在运行时发生的编译错误(通常情况下)。 - Ed Chapel
1
在这个 Html.Hidden("Name", "Value") 中,我得到了这个 <input id="Name" name="Name" type="hidden" value="Value"> - Stas BZ
@StasBZ 是的,那是预期的结果。 - Kirk Woll

16

Html.Hidden会创建一个隐藏的输入框,但你需要指定该字段的名称和所有属性以及值。而Html.HiddenFor则会为您传递给它的对象创建一个隐藏的输入框,它们看起来像这样:

Html.Hidden("yourProperty",model.yourProperty);

Html.HiddenFor(m => m.yourProperty)

在这种情况下,输出结果相同!


那么,简而言之,hidden是由代码创建的东西,而hiddenfor是对你在代码中创建的内容的引用,对吗? - Venzentx
2
twocode -- 不,它们都是由代码创建的,但编译器可以从表达式中检测到实际属性名称,从而使模型保持一致。这用于自动模型绑定。 - Gerard ONeill

7

HtmlHelper类中的每个方法都有一个带有For后缀的对应方法。 Html.Hidden方法需要一个字符串作为参数,但是Html.HiddenFor方法需要一个表达式作为参数。如果你的视图是强类型视图,你可以受益于这一点,并像下面这样传递一个lambda表达式给该方法。

o=>o.SomeProperty 

在使用Html.Hidden方法时,需要用"SomeProperty"替换。

感谢Jani提供有关Helper Twins的信息。 - Joe Pitz

3

Html.Hidden('name', 'value')创建一个名为“name”且值为“value”的隐藏标签。

Html.HiddenFor(x => x.nameProp)创建一个名为“nameProp”且值为x.nameProp的隐藏标签。

表面上看,它们似乎做了类似的事情,只是其中一个更方便。但它的实际价值在于模型绑定。当MVC尝试将html关联到模型时,它需要具有属性的名称,对于Html.Hidden,我们选择了“name”,而不是“nameProp”,因此绑定将无法工作。您必须拥有自定义绑定对象或从表单数据获取值。如果您正在重新显示页面,则必须再次将模型设置为这些值。

因此,您可以使用Html.Hidden,但是如果您将名称弄错了,或者如果您更改了模型中的属性名称,则提交表单时自动绑定将失败。但是,通过使用类型检查的表达式,您将获得代码完成,并且当您更改属性名称时,您将获得编译时错误。然后,您保证在表单中具有正确的名称。

MVC的最佳功能之一。


3

Html.Hidden和Html.HiddenFor用于生成名称-值对,这些名称-值对由控制器中的操作方法等待。

示例用法(*):

@using (Html.BeginForm("RemoveFromCart", "Cart")) {
                    @Html.Hidden("ProductId", line.Product.ProductID)
                    @Html.HiddenFor(x => x.ReturnUrl)
                    <input class="btn btn-sm btn-warning"
                           type="submit" value="Remove" />
                }

如果您的操作方法需要等待“ProductId”,则必须使用(Html.Hidden或Html.HiddenFor)在表单中生成此名称。 如果无法使用强类型模型生成此名称,则可以使用字符串“ProductId”直接写入该名称。
public ViewResult RemoveFromCart(int productId, string returnUrl){...}

如果我已经写了Html.HiddenFor(x => line.Product.ProductID),那么该帮助程序将呈现一个名称为"line.Product.ProductID"的隐藏字段。该字段的名称将不匹配“RemoveFromCart”操作方法的参数名称,该方法等待“ProductId”的名称。这将防止默认模型绑定器工作,因此MVC框架将无法调用该方法。

2

我希望能够补充已经解释过的内容。

  • 主要区别在于HiddenFor是强类型,而Hidden不是。
  • 两者都位于:System.Web.Mvc.Html
  • 两种方法都返回:MvcHtmlString——一个type属性设置为“hidden”的输入元素。

官方文档解释如下:

@Html.Hidden()

https://learn.microsoft.com/en-us/dotnet/api/system.web.mvc.html.inputextensions.hidden?view=aspnet-mvc-5.2

Hidden(HtmlHelper, String, Object, Object)  

使用指定的HTML助手、表单字段名称、值和HTML属性,返回隐藏的输入元素。
Hidden(HtmlHelper, String, Object, IDictionary<String,Object>)

使用指定的HTML助手、表单字段名称、值和HTML属性,返回隐藏输入元素。
Hidden(HtmlHelper, String, Object)

使用指定的HTML助手和表单字段名称,返回一个隐藏的输入元素。
Hidden(HtmlHelper, String)

参数:

  • name: 表单字段的名称和ViewDataDictionary键,用于查找值。
  • value: 隐藏输入元素的值。按以下顺序检索值 - ModelStateDictionary对象、此参数的值、ViewDataDictionary对象以及html属性中的value属性。

@Html.HiddenFor()

https://learn.microsoft.com/en-us/dotnet/api/system.web.mvc.html.inputextensions.hiddenfor?view=aspnet-mvc-5.2

HiddenFor<TModel,TProperty>(HtmlHelper<TModel>, Expression<Func<TModel,TProperty>>)
  • 根据指定的表达式,为对象中的每个属性返回一个HTML隐藏输入元素。
HiddenFor<TModel,TProperty>
    (HtmlHelper<TModel>, 
     Expression<Func<TModel,TProperty>>,
     IDictionary<String,Object>)    
  • 使用指定的HTML属性,为由指定表达式表示的对象中的每个属性返回一个HTML隐藏输入元素。
HiddenFor<TModel,TProperty>(HtmlHelper<TModel>, Expression<Func<TModel,TProperty>>, Object)
  • 使用指定的HTML属性,为由指定表达式表示的对象中的每个属性返回一个HTML隐藏输入元素。

其中:

  • TModel:模型的类型。
  • TProperty:属性的类型。
  • expression:标识包含要呈现的属性的对象的表达式。

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